1e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompackage org.bouncycastle.cms; 2e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 3e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.io.IOException; 4e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.io.OutputStream; 5e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.NoSuchAlgorithmException; 6e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.NoSuchProviderException; 7e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.Provider; 8e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.PublicKey; 9e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.cert.CertificateExpiredException; 10e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.cert.CertificateNotYetValidException; 11e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.security.cert.X509Certificate; 12e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.ArrayList; 13e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.Enumeration; 14e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.Iterator; 15e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.List; 16e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 17e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1Encodable; 18e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1EncodableVector; 19e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1Encoding; 20e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1ObjectIdentifier; 21e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1OctetString; 22e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1Primitive; 23e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1Set; 2470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstromimport org.bouncycastle.asn1.DERNull; 25e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.DERSet; 26e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.Attribute; 27e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.AttributeTable; 28e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.CMSAttributes; 29e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.IssuerAndSerialNumber; 30e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.SignerIdentifier; 31e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.SignerInfo; 32e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.Time; 33e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.x509.AlgorithmIdentifier; 34e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.x509.DigestInfo; 35e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.cert.X509CertificateHolder; 36e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.cms.jcajce.JcaSignerInfoVerifierBuilder; 37e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; 38e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.ContentVerifier; 39e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.DigestCalculator; 40e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.OperatorCreationException; 41e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.RawContentVerifier; 42e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; 43e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.util.Arrays; 4470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstromimport org.bouncycastle.util.io.TeeOutputStream; 45e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 46e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom/** 47e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * an expanded SignerInfo block from a CMS Signed message 48e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 49e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompublic class SignerInformation 50e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom{ 51e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private SignerId sid; 52e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private SignerInfo info; 53e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private AlgorithmIdentifier digestAlgorithm; 54e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private AlgorithmIdentifier encryptionAlgorithm; 55e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private final ASN1Set signedAttributeSet; 56e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private final ASN1Set unsignedAttributeSet; 57e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private CMSProcessable content; 58e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private byte[] signature; 59e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private ASN1ObjectIdentifier contentType; 60e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private byte[] resultDigest; 61e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 62e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // Derived 63e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private AttributeTable signedAttributeValues; 64e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private AttributeTable unsignedAttributeValues; 65e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private boolean isCounterSignature; 66e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 67e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInformation( 68e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInfo info, 69e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1ObjectIdentifier contentType, 70e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CMSProcessable content, 71e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom byte[] resultDigest) 72e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 73e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.info = info; 74e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.contentType = contentType; 75e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.isCounterSignature = contentType == null; 76e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 77e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerIdentifier s = info.getSID(); 78e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 79e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (s.isTagged()) 80e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 81e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1OctetString octs = ASN1OctetString.getInstance(s.getId()); 82e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 83e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom sid = new SignerId(octs.getOctets()); 84e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 85e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom else 86e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 87e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom IssuerAndSerialNumber iAnds = IssuerAndSerialNumber.getInstance(s.getId()); 88e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 89e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom sid = new SignerId(iAnds.getName(), iAnds.getSerialNumber().getValue()); 90e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 91e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 92e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.digestAlgorithm = info.getDigestAlgorithm(); 93e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.signedAttributeSet = info.getAuthenticatedAttributes(); 94e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.unsignedAttributeSet = info.getUnauthenticatedAttributes(); 95e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.encryptionAlgorithm = info.getDigestEncryptionAlgorithm(); 96e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.signature = info.getEncryptedDigest().getOctets(); 97e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 98e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.content = content; 99e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom this.resultDigest = resultDigest; 100e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 101e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 102e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public boolean isCounterSignature() 103e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 104e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return isCounterSignature; 105e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 106e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 107e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public ASN1ObjectIdentifier getContentType() 108e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 109e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return this.contentType; 110e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 111e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 112e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private byte[] encodeObj( 113e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1Encodable obj) 114e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws IOException 115e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 116e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (obj != null) 117e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 118e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return obj.toASN1Primitive().getEncoded(); 119e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 120e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 121e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return null; 122e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 123e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 124e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public SignerId getSID() 125e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 126e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return sid; 127e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 128e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 129e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 130e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return the version number for this objects underlying SignerInfo structure. 131e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 132e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public int getVersion() 133e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 134e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return info.getVersion().getValue().intValue(); 135e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 136e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 137e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public AlgorithmIdentifier getDigestAlgorithmID() 138e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 139e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return digestAlgorithm; 140e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 141e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 142e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 143e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return the object identifier for the signature. 144e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 145e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public String getDigestAlgOID() 146e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 14770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom return digestAlgorithm.getAlgorithm().getId(); 148e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 149e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 150e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 151e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return the signature parameters, or null if there aren't any. 152e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 153e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public byte[] getDigestAlgParams() 154e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 155e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom try 156e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 157e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return encodeObj(digestAlgorithm.getParameters()); 158e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 159e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom catch (Exception e) 160e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 161e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new RuntimeException("exception getting digest parameters " + e); 162e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 163e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 164e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 165e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 166e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return the content digest that was calculated during verification. 167e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 168e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public byte[] getContentDigest() 169e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 170e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (resultDigest == null) 171e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 172e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new IllegalStateException("method can only be called after verify."); 173e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 174e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 175e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return (byte[])resultDigest.clone(); 176e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 177e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 178e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 179e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return the object identifier for the signature. 180e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 181e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public String getEncryptionAlgOID() 182e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 18370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom return encryptionAlgorithm.getAlgorithm().getId(); 184e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 185e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 186e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 187e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return the signature/encryption algorithm parameters, or null if 188e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * there aren't any. 189e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 190e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public byte[] getEncryptionAlgParams() 191e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 192e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom try 193e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 194e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return encodeObj(encryptionAlgorithm.getParameters()); 195e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 196e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom catch (Exception e) 197e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 198e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new RuntimeException("exception getting encryption parameters " + e); 199e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 200e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 201e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 202e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 203e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return a table of the signed attributes - indexed by 204e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * the OID of the attribute. 205e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 206e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public AttributeTable getSignedAttributes() 207e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 208e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (signedAttributeSet != null && signedAttributeValues == null) 209e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 210e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom signedAttributeValues = new AttributeTable(signedAttributeSet); 211e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 212e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 213e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return signedAttributeValues; 214e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 215e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 216e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 217e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return a table of the unsigned attributes indexed by 218e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * the OID of the attribute. 219e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 220e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public AttributeTable getUnsignedAttributes() 221e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 222e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (unsignedAttributeSet != null && unsignedAttributeValues == null) 223e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 224e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom unsignedAttributeValues = new AttributeTable(unsignedAttributeSet); 225e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 226e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 227e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return unsignedAttributeValues; 228e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 229e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 230e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 231e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return the encoded signature 232e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 233e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public byte[] getSignature() 234e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 235e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return (byte[])signature.clone(); 236e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 237e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 238e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 239e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Return a SignerInformationStore containing the counter signatures attached to this 240e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * signer. If no counter signatures are present an empty store is returned. 241e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 242e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public SignerInformationStore getCounterSignatures() 243e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 244e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // TODO There are several checks implied by the RFC3852 comments that are missing 245e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 246e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /* 247e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom The countersignature attribute MUST be an unsigned attribute; it MUST 248e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom NOT be a signed attribute, an authenticated attribute, an 249e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom unauthenticated attribute, or an unprotected attribute. 250e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 251e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom AttributeTable unsignedAttributeTable = getUnsignedAttributes(); 252e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (unsignedAttributeTable == null) 253e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 254e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return new SignerInformationStore(new ArrayList(0)); 255e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 256e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 257e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom List counterSignatures = new ArrayList(); 258e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 259e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /* 260e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom The UnsignedAttributes syntax is defined as a SET OF Attributes. The 261e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom UnsignedAttributes in a signerInfo may include multiple instances of 262e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom the countersignature attribute. 263e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 264e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1EncodableVector allCSAttrs = unsignedAttributeTable.getAll(CMSAttributes.counterSignature); 265e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 266e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom for (int i = 0; i < allCSAttrs.size(); ++i) 267e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 268e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Attribute counterSignatureAttribute = (Attribute)allCSAttrs.get(i); 269e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 270e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /* 271e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom A countersignature attribute can have multiple attribute values. The 272e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom syntax is defined as a SET OF AttributeValue, and there MUST be one 273e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom or more instances of AttributeValue present. 274e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 275e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1Set values = counterSignatureAttribute.getAttrValues(); 276e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (values.size() < 1) 277e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 278e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // TODO Throw an appropriate exception? 279e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 280e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 281e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom for (Enumeration en = values.getObjects(); en.hasMoreElements();) 282e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 283e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /* 284e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Countersignature values have the same meaning as SignerInfo values 285e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom for ordinary signatures, except that: 286e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 287e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 1. The signedAttributes field MUST NOT contain a content-type 288e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom attribute; there is no content type for countersignatures. 289e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 290e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 2. The signedAttributes field MUST contain a message-digest 291e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom attribute if it contains any other attributes. 292e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 293e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 3. The input to the message-digesting process is the contents 294e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom octets of the DER encoding of the signatureValue field of the 295e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInfo value with which the attribute is associated. 296e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 297e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInfo si = SignerInfo.getInstance(en.nextElement()); 298e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 299e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom counterSignatures.add(new SignerInformation(si, null, new CMSProcessableByteArray(getSignature()), null)); 300e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 301e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 302e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 303e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return new SignerInformationStore(counterSignatures); 304e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 305e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 306e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 307e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * return the DER encoding of the signed attributes. 308e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @throws IOException if an encoding error occurs. 309e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 310e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public byte[] getEncodedSignedAttributes() 311e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws IOException 312e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 313e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (signedAttributeSet != null) 314e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 315e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return signedAttributeSet.getEncoded(); 316e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 317e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 318e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return null; 319e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 320e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 321e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 322e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @deprecated 323e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 324e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private boolean doVerify( 325e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom PublicKey key, 326e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Provider sigProvider) 327e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws CMSException, NoSuchAlgorithmException 328e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 329e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom try 330e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 331e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInformationVerifier verifier; 332e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 333e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (sigProvider != null) 334e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 335e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (!sigProvider.getName().equalsIgnoreCase("BC")) 336e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 337e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom verifier = new JcaSignerInfoVerifierBuilder(new JcaDigestCalculatorProviderBuilder().build()).setProvider(sigProvider).build(key); 338e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 339e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom else 340e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 341e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom verifier = new JcaSimpleSignerInfoVerifierBuilder().setProvider(sigProvider).build(key); 342e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 343e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 344e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom else 345e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 346e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom verifier = new JcaSimpleSignerInfoVerifierBuilder().build(key); 347e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 348e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 349e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return doVerify(verifier); 350e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 351e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom catch (OperatorCreationException e) 352e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 353e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("unable to create verifier: " + e.getMessage(), e); 354e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 355e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 356e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 357e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private boolean doVerify( 358e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInformationVerifier verifier) 359e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws CMSException 360e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 361e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID()); 36270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom ContentVerifier contentVerifier; 363e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 364e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom try 365e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 36670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom contentVerifier = verifier.getContentVerifier(encryptionAlgorithm, info.getDigestAlgorithm()); 36770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 36870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom catch (OperatorCreationException e) 36970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 37070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom throw new CMSException("can't create content verifier: " + e.getMessage(), e); 37170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 37270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 37370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom try 37470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 37570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom OutputStream sigOut = contentVerifier.getOutputStream(); 37670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 377e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (resultDigest == null) 378e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 379e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID()); 380e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (content != null) 381e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 382e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom OutputStream digOut = calc.getOutputStream(); 383e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 38470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (signedAttributeSet == null) 38570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 38670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (contentVerifier instanceof RawContentVerifier) 38770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 38870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom content.write(digOut); 38970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 39070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom else 39170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 39270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom OutputStream cOut = new TeeOutputStream(digOut, sigOut); 39370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 39470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom content.write(cOut); 39570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 39670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom cOut.close(); 39770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 39870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 39970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom else 40070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 40170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom content.write(digOut); 40270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom sigOut.write(this.getEncodedSignedAttributes()); 40370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 404e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 405e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom digOut.close(); 406e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 40770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom else if (signedAttributeSet != null) 40870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 40970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom sigOut.write(this.getEncodedSignedAttributes()); 41070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 41170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom else 412e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 413e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // TODO Get rid of this exception and just treat content==null as empty not missing? 414e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("data not encapsulated in signature - use detached constructor."); 415e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 416e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 417e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom resultDigest = calc.getDigest(); 418e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 41970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom else 42070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 42170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (signedAttributeSet == null) 42270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 42370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (content != null) 42470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 42570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom content.write(sigOut); 42670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 42770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 42870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom else 42970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 43070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom sigOut.write(this.getEncodedSignedAttributes()); 43170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 43270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 43370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 43470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom sigOut.close(); 435e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 436e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom catch (IOException e) 437e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 438e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("can't process mime object to create signature.", e); 439e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 440e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom catch (OperatorCreationException e) 441e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 442e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("can't create digest calculator: " + e.getMessage(), e); 443e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 444e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 445e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // RFC 3852 11.1 Check the content-type attribute is correct 446e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 447e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1Primitive validContentType = getSingleValuedSignedAttribute( 448e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CMSAttributes.contentType, "content-type"); 449e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (validContentType == null) 450e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 451e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (!isCounterSignature && signedAttributeSet != null) 452e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 453e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data"); 454e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 455e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 456e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom else 457e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 458e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (isCounterSignature) 459e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 460e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute"); 461e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 462e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 46370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (!(validContentType instanceof ASN1ObjectIdentifier)) 464e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 465e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'"); 466e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 467e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 46870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom ASN1ObjectIdentifier signedContentType = (ASN1ObjectIdentifier)validContentType; 469e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 470e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (!signedContentType.equals(contentType)) 471e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 472e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("content-type attribute value does not match eContentType"); 473e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 474e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 475e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 476e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 477e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // RFC 3852 11.2 Check the message-digest attribute is correct 478e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 479e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute( 480e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CMSAttributes.messageDigest, "message-digest"); 481e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (validMessageDigest == null) 482e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 483e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (signedAttributeSet != null) 484e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 485e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("the message-digest signed attribute type MUST be present when there are any signed attributes present"); 486e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 487e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 488e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom else 489e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 490e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (!(validMessageDigest instanceof ASN1OctetString)) 491e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 492e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'"); 493e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 494e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 495e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1OctetString signedMessageDigest = (ASN1OctetString)validMessageDigest; 496e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 497e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets())) 498e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 499e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSSignerDigestMismatchException("message-digest attribute value does not match calculated value"); 500e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 501e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 502e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 503e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 504e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // RFC 3852 11.4 Validate countersignature attribute(s) 505e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 506e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom AttributeTable signedAttrTable = this.getSignedAttributes(); 507e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (signedAttrTable != null 508e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0) 509e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 510e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("A countersignature attribute MUST NOT be a signed attribute"); 511e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 512e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 513e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom AttributeTable unsignedAttrTable = this.getUnsignedAttributes(); 514e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (unsignedAttrTable != null) 515e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 516e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature); 517e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom for (int i = 0; i < csAttrs.size(); ++i) 518e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 519e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Attribute csAttr = (Attribute)csAttrs.get(i); 520e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (csAttr.getAttrValues().size() < 1) 521e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 522e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue"); 523e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 524e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 525e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // Note: We don't recursively validate the countersignature value 526e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 527e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 528e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 529e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 530e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom try 531e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 53270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (signedAttributeSet == null && resultDigest != null) 533e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 53470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (contentVerifier instanceof RawContentVerifier) 535e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 53670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom RawContentVerifier rawVerifier = (RawContentVerifier)contentVerifier; 537e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 53870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (encName.equals("RSA")) 53970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 54070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom DigestInfo digInfo = new DigestInfo(new AlgorithmIdentifier(digestAlgorithm.getAlgorithm(), DERNull.INSTANCE), resultDigest); 541e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 54270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom return rawVerifier.verify(digInfo.getEncoded(ASN1Encoding.DER), this.getSignature()); 543e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 544e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 54570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom return rawVerifier.verify(resultDigest, this.getSignature()); 546e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 547e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 548e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 549e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return contentVerifier.verify(this.getSignature()); 550e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 551e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom catch (IOException e) 552e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 553e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("can't process mime object to create signature.", e); 554e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 555e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 556e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 557e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 558e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * verify that the given public key successfully handles and confirms the 559e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * signature associated with this signer. 560e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @deprecated use verify(ContentVerifierProvider) 561e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 562e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public boolean verify( 563e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom PublicKey key, 564e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom String sigProvider) 565e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws NoSuchAlgorithmException, NoSuchProviderException, CMSException 566e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 567e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return verify(key, CMSUtils.getProvider(sigProvider)); 568e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 569e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 570e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 571e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * verify that the given public key successfully handles and confirms the 572e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * signature associated with this signer 573e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @deprecated use verify(ContentVerifierProvider) 574e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 575e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public boolean verify( 576e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom PublicKey key, 577e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Provider sigProvider) 578e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws NoSuchAlgorithmException, NoSuchProviderException, CMSException 579e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 580e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // Optional, but still need to validate if present 581e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom getSigningTime(); 582e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 583e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return doVerify(key, sigProvider); 584e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 585e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 586e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 587e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * verify that the given certificate successfully handles and confirms 588e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * the signature associated with this signer and, if a signingTime 589e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * attribute is available, that the certificate was valid at the time the 590e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * signature was generated. 591e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @deprecated use verify(ContentVerifierProvider) 592e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 593e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public boolean verify( 594e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom X509Certificate cert, 595e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom String sigProvider) 596e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws NoSuchAlgorithmException, NoSuchProviderException, 597e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CertificateExpiredException, CertificateNotYetValidException, 598e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CMSException 599e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 600e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return verify(cert, CMSUtils.getProvider(sigProvider)); 601e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 602e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 603e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 604e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * verify that the given certificate successfully handles and confirms 605e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * the signature associated with this signer and, if a signingTime 606e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * attribute is available, that the certificate was valid at the time the 607e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * signature was generated. 608e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @deprecated use verify(ContentVerifierProvider) 609e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 610e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public boolean verify( 611e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom X509Certificate cert, 612e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Provider sigProvider) 613e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws NoSuchAlgorithmException, 614e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CertificateExpiredException, CertificateNotYetValidException, 615e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CMSException 616e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 617e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Time signingTime = getSigningTime(); 618e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (signingTime != null) 619e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 620e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom cert.checkValidity(signingTime.getDate()); 621e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 622e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 623e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return doVerify(cert.getPublicKey(), sigProvider); 624e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 625e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 626e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 627e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Verify that the given verifier can successfully verify the signature on 628e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * this SignerInformation object. 629e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 630e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param verifier a suitably configured SignerInformationVerifier. 631e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @return true if the signer information is verified, false otherwise. 632e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @throws org.bouncycastle.cms.CMSVerifierCertificateNotValidException if the provider has an associated certificate and the certificate is not valid at the time given as the SignerInfo's signing time. 633e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @throws org.bouncycastle.cms.CMSException if the verifier is unable to create a ContentVerifiers or DigestCalculators. 634e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 635e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public boolean verify(SignerInformationVerifier verifier) 636e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws CMSException 637e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 638e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Time signingTime = getSigningTime(); // has to be validated if present. 639e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 640e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (verifier.hasAssociatedCertificate()) 641e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 642e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (signingTime != null) 643e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 644e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom X509CertificateHolder dcv = verifier.getAssociatedCertificate(); 645e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 646e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (!dcv.isValidOn(signingTime.getDate())) 647e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 648e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSVerifierCertificateNotValidException("verifier not valid at signingTime"); 649e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 650e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 651e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 652e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 653e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return doVerify(verifier); 654e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 655e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 656e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 657e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Return the base ASN.1 CMS structure that this object contains. 658e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 659e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @return an object containing a CMS SignerInfo structure. 660e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @deprecated use toASN1Structure() 661e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 662e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public SignerInfo toSignerInfo() 663e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 664e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return info; 665e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 666e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 667e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 668e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Return the underlying ASN.1 object defining this SignerInformation object. 669e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 670e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @return a SignerInfo. 671e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 672e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public SignerInfo toASN1Structure() 673e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 674e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return info; 675e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 676e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 677e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private ASN1Primitive getSingleValuedSignedAttribute( 678e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1ObjectIdentifier attrOID, String printableName) 679e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws CMSException 680e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 681e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom AttributeTable unsignedAttrTable = this.getUnsignedAttributes(); 682e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (unsignedAttrTable != null 683e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom && unsignedAttrTable.getAll(attrOID).size() > 0) 684e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 685e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("The " + printableName 686e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom + " attribute MUST NOT be an unsigned attribute"); 687e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 688e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 689e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom AttributeTable signedAttrTable = this.getSignedAttributes(); 690e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (signedAttrTable == null) 691e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 692e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return null; 693e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 694e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 695e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1EncodableVector v = signedAttrTable.getAll(attrOID); 696e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom switch (v.size()) 697e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 698e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom case 0: 699e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return null; 700e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom case 1: 701e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 702e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom Attribute t = (Attribute)v.get(0); 703e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1Set attrValues = t.getAttrValues(); 704e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (attrValues.size() != 1) 705e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 706e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("A " + printableName 707e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom + " attribute MUST have a single attribute value"); 708e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 709e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 710e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return attrValues.getObjectAt(0).toASN1Primitive(); 711e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 712e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom default: 713e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("The SignedAttributes in a signerInfo MUST NOT include multiple instances of the " 714e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom + printableName + " attribute"); 715e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 716e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 717e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 718e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private Time getSigningTime() throws CMSException 719e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 720e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1Primitive validSigningTime = getSingleValuedSignedAttribute( 721e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CMSAttributes.signingTime, "signing-time"); 722e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 723e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (validSigningTime == null) 724e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 725e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return null; 726e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 727e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 728e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom try 729e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 730e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return Time.getInstance(validSigningTime); 731e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 732e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom catch (IllegalArgumentException e) 733e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 734e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("signing-time attribute value not a valid 'Time' structure"); 735e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 736e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 737e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 738e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 739e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Return a signer information object with the passed in unsigned 740e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * attributes replacing the ones that are current associated with 741e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * the object passed in. 742e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 743e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param signerInformation the signerInfo to be used as the basis. 744e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param unsignedAttributes the unsigned attributes to add. 745e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @return a copy of the original SignerInformationObject with the changed attributes. 746e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 747e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public static SignerInformation replaceUnsignedAttributes( 748e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInformation signerInformation, 749e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom AttributeTable unsignedAttributes) 750e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 751e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInfo sInfo = signerInformation.info; 752e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1Set unsignedAttr = null; 753e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 754e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (unsignedAttributes != null) 755e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 756e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom unsignedAttr = new DERSet(unsignedAttributes.toASN1EncodableVector()); 757e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 758e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 759e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return new SignerInformation( 760e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(), 761e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), unsignedAttr), 762e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom signerInformation.contentType, signerInformation.content, null); 763e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 764e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 765e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 766e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Return a signer information object with passed in SignerInformationStore representing counter 767e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * signatures attached as an unsigned attribute. 768e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 769e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param signerInformation the signerInfo to be used as the basis. 770e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param counterSigners signer info objects carrying counter signature. 771e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @return a copy of the original SignerInformationObject with the changed attributes. 772e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 773e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public static SignerInformation addCounterSigners( 774e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInformation signerInformation, 775e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInformationStore counterSigners) 776e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 777e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // TODO Perform checks from RFC 3852 11.4 778e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 779e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInfo sInfo = signerInformation.info; 780e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom AttributeTable unsignedAttr = signerInformation.getUnsignedAttributes(); 781e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1EncodableVector v; 782e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 783e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (unsignedAttr != null) 784e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 785e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom v = unsignedAttr.toASN1EncodableVector(); 786e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 787e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom else 788e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 789e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom v = new ASN1EncodableVector(); 790e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 791e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 792e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1EncodableVector sigs = new ASN1EncodableVector(); 793e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 794e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom for (Iterator it = counterSigners.getSigners().iterator(); it.hasNext();) 795e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 79670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom sigs.add(((SignerInformation)it.next()).toASN1Structure()); 797e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 798e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 799e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom v.add(new Attribute(CMSAttributes.counterSignature, new DERSet(sigs))); 800e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 801e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return new SignerInformation( 802e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom new SignerInfo(sInfo.getSID(), sInfo.getDigestAlgorithm(), 803e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom sInfo.getAuthenticatedAttributes(), sInfo.getDigestEncryptionAlgorithm(), sInfo.getEncryptedDigest(), new DERSet(v)), 804e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom signerInformation.contentType, signerInformation.content, null); 805e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 806e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom} 807