package de.persosim.simulator.protocols.ca; import java.security.InvalidParameterException; import java.util.Arrays; import de.persosim.simulator.crypto.CryptoSupport; import de.persosim.simulator.crypto.CryptoSupportAes; import de.persosim.simulator.crypto.CryptoUtil; import de.persosim.simulator.protocols.GenericOid; import de.persosim.simulator.utils.HexString; public class CaOid extends GenericOid implements Ca { private String idString; /** * This constructor constructs a {@link CaOid} based on a byte array representation of a CA OID. * @param oidByteArray the byte array representation of a CA OID */ public CaOid(byte[] oidByteArray) { super(oidByteArray); //check if provided OID is indeed CaOID idString =getStringRepresentation (oidByteArray); if(idString == null) { throw new IllegalArgumentException("CA OID " + HexString.encode(oidByteArray) + " is invalid or unknown (not supported)"); } } /*----------------------------------------------------------------*/ /** * This method returns the OID's byte indicating the key agreement * @return the OID's byte indicating the key agreement */ public byte getKeyAgreementAsByte() { return this.oidByteArray[8]; } /** * This method returns the OID's byte indicating the symmetric cipher and key size * @return the OID's byte indicating the symmetric cipher and key size */ public byte getSymmetricCipherAndKeySizeAsByte() { return this.oidByteArray[9]; } /*----------------------------------------------------------------*/ /** * This method returns the common name of the used key agreement. * @return the common name of the used key agreement */ public String getKeyAgreementName() { switch (this.getKeyAgreementAsByte()) { case Ca.DH: return "DH"; case Ca.ECDH: return "ECDH"; default: throw new InvalidParameterException("no or invalid key agreement selected"); } } protected CryptoSupport cryptoSupportCache = null; /** * This method returns the {@link CryptoSupport} object matching the crypto systems indicated by the OID. * @return the {@link CryptoSupport} object matching the crypto systems indicated by the OID */ public CryptoSupport getCryptoSupport() { if(cryptoSupportCache == null) { String cipherName = getSymmetricCipherAlgorithmNameModePadding(); String macName = getMacName(); switch (CryptoUtil.getCipherNameAsString(cipherName)) { case "AES": cryptoSupportCache = new CryptoSupportAes(cipherName, macName); break; default: throw new IllegalArgumentException("algorithm " + cipherName + " is unknown or not supported"); } } return cryptoSupportCache; } /*----------------------------------------------------------------*/ /** * This method returns the used cipher algorithm name including name, mode * of operation and used padding. * * @return the used cipher algorithm name, mode and padding */ public String getSymmetricCipherAlgorithmNameModePadding() { switch (this.getSymmetricCipherAndKeySizeAsByte()) { case Ca.AES_CBC_CMAC_128: return "AES/CBC/NoPadding"; case Ca.AES_CBC_CMAC_192: return "AES/CBC/NoPadding"; case Ca.AES_CBC_CMAC_256: return "AES/CBC/NoPadding"; default: throw new InvalidParameterException("no or invalid symmetric cipher selected"); } } /** * This method returns the used cipher algorithm's name, i.e. "AES". * @return the used cipher algorithm's name */ public String getSymmetricCipherAlgorithmName() { return CryptoUtil.getCipherNameAsString(this.getSymmetricCipherAlgorithmNameModePadding()); } /** * This method returns the used cipher algorithm's mode of operation, i.e. "CBC". * @return the used cipher algorithm's mode of operation */ public String getSymmetricCipherAlgorithmMode() { return CryptoUtil.getCipherAlgorithmModeAsString(this.getSymmetricCipherAlgorithmNameModePadding()); } /** * This method returns the used cipher algorithm's padding, i.e. "NoPadding". * @return the used cipher algorithm's padding */ public String getSymmetricCipherAlgorithmPadding() { return CryptoUtil.getCipherAlgorithmPaddingAsString(this.getSymmetricCipherAlgorithmNameModePadding()); } /** * This method returns the key length in bytes to be used with the symmetric cipher implied by the OID. * @return the key length in byte as indicated by the OID */ public int getSymmetricCipherKeyLengthInBytes() { switch (this.getSymmetricCipherAndKeySizeAsByte()) { case Ca.AES_CBC_CMAC_128: return 16; case Ca.AES_CBC_CMAC_192: return 24; case Ca.AES_CBC_CMAC_256: return 32; default: throw new InvalidParameterException("no or invalid symmetric cipher selected"); } } /** * This method returns the MAC name indicated by the OID. * @return the MAC name indicated by the OID */ public String getMacName() { switch (this.getSymmetricCipherAlgorithmName()) { case "AES": return "aescmac"; default: throw new InvalidParameterException("no or invalid mac selected"); } } /*----------------------------------------------------------------*/ /** * @see Oid#getIdString() * @return common name of OID or null if parameter does not encode a CaOid */ public String getStringRepresentation(byte[] oidByteArray) { if (Arrays.equals(oidByteArray, id_CA_DH_AES_CBC_CMAC_128)) return id_CA_DH_AES_CBC_CMAC_128_STRING; if (Arrays.equals(oidByteArray, id_CA_DH_AES_CBC_CMAC_192)) return id_CA_DH_AES_CBC_CMAC_192_STRING; if (Arrays.equals(oidByteArray, id_CA_DH_AES_CBC_CMAC_256)) return id_CA_DH_AES_CBC_CMAC_256_STRING; if (Arrays.equals(oidByteArray, id_CA_ECDH_AES_CBC_CMAC_128)) return id_CA_ECDH_AES_CBC_CMAC_128_STRING; if (Arrays.equals(oidByteArray, id_CA_ECDH_AES_CBC_CMAC_192)) return id_CA_ECDH_AES_CBC_CMAC_192_STRING; if (Arrays.equals(oidByteArray, id_CA_ECDH_AES_CBC_CMAC_256)) return id_CA_ECDH_AES_CBC_CMAC_256_STRING; return null; } @Override public String getIdString() { return idString; } }