1e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompackage org.bouncycastle.cert.selector; 2e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 3e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.math.BigInteger; 4e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 5e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1OctetString; 6e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.IssuerAndSerialNumber; 7e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.x500.X500Name; 8e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.x509.Extension; 9e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.cert.X509CertificateHolder; 10e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.util.Arrays; 11e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.util.Selector; 12e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 13e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom/** 14e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * a basic index for a X509CertificateHolder class 15e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 16e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompublic class X509CertificateHolderSelector 17e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom implements Selector 18e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom{ 19e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private byte[] subjectKeyId; 20e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 21e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private X500Name issuer; 22e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private BigInteger serialNumber; 23e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 24e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 25e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Construct a selector with the value of a public key's subjectKeyId. 26e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 27e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param subjectKeyId a subjectKeyId 28e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 29e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public X509CertificateHolderSelector(byte[] subjectKeyId) 30e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 31e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this(null, null, subjectKeyId); 32e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 33e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 34e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 35e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Construct a signer ID based on the issuer and serial number of the signer's associated 36e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * certificate. 37e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 38e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param issuer the issuer of the signer's associated certificate. 39e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param serialNumber the serial number of the signer's associated certificate. 40e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 41e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public X509CertificateHolderSelector(X500Name issuer, BigInteger serialNumber) 42e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 43e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this(issuer, serialNumber, null); 44e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 45e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 46e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 47e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Construct a signer ID based on the issuer and serial number of the signer's associated 48e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * certificate. 49e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 50e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param issuer the issuer of the signer's associated certificate. 51e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param serialNumber the serial number of the signer's associated certificate. 52e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param subjectKeyId the subject key identifier to use to match the signers associated certificate. 53e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 54e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public X509CertificateHolderSelector(X500Name issuer, BigInteger serialNumber, byte[] subjectKeyId) 55e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 56e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.issuer = issuer; 57e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.serialNumber = serialNumber; 58e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.subjectKeyId = subjectKeyId; 59e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 60e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 61e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public X500Name getIssuer() 62e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 63e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return issuer; 64e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 65e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 66e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public BigInteger getSerialNumber() 67e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 68e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return serialNumber; 69e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 70e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 71e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public byte[] getSubjectKeyIdentifier() 72e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 73e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return Arrays.clone(subjectKeyId); 74e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 75e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 76e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public int hashCode() 77e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 78e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom int code = Arrays.hashCode(subjectKeyId); 79e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 80e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (this.serialNumber != null) 81e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 82e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom code ^= this.serialNumber.hashCode(); 83e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 84e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 85e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (this.issuer != null) 86e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 87e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom code ^= this.issuer.hashCode(); 88e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 89e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 90e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return code; 91e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 92e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 93e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public boolean equals( 94e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Object o) 95e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 96e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (!(o instanceof X509CertificateHolderSelector)) 97e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 98e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return false; 99e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 100e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 101e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom X509CertificateHolderSelector id = (X509CertificateHolderSelector)o; 102e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 103e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return Arrays.areEqual(subjectKeyId, id.subjectKeyId) 104e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom && equalsObj(this.serialNumber, id.serialNumber) 105e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom && equalsObj(this.issuer, id.issuer); 106e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 107e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 108e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private boolean equalsObj(Object a, Object b) 109e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 110e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return (a != null) ? a.equals(b) : b == null; 111e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 112e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 113e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public boolean match(Object obj) 114e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 115e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (obj instanceof X509CertificateHolder) 116e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 117e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom X509CertificateHolder certHldr = (X509CertificateHolder)obj; 118e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 119e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (this.getSerialNumber() != null) 120e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 121e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom IssuerAndSerialNumber iAndS = new IssuerAndSerialNumber(certHldr.toASN1Structure()); 122e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 123e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return iAndS.getName().equals(this.issuer) 124e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom && iAndS.getSerialNumber().getValue().equals(this.serialNumber); 125e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 126e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom else if (subjectKeyId != null) 127e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 128e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Extension ext = certHldr.getExtension(Extension.subjectKeyIdentifier); 129e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 130e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (ext == null) 131e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 132e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return Arrays.areEqual(subjectKeyId, MSOutlookKeyIdCalculator.calculateKeyId(certHldr.getSubjectPublicKeyInfo())); 133e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 134e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 135e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom byte[] subKeyID = ASN1OctetString.getInstance(ext.getParsedValue()).getOctets(); 136e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 137e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return Arrays.areEqual(subjectKeyId, subKeyID); 138e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 139e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 140e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom else if (obj instanceof byte[]) 141e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 142e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return Arrays.areEqual(subjectKeyId, (byte[])obj); 143e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 144e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 145e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return false; 146e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 147e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 148e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public Object clone() 149e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 150e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return new X509CertificateHolderSelector(this.issuer, this.serialNumber, this.subjectKeyId); 151e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 152e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom} 153