Java tutorial
package org.bouncycastle.asn1.cms; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** * <a href="http://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>: * Signature container per Signer, see {@link SignerIdentifier}. * <pre> * PKCS#7: * * SignerInfo ::= SEQUENCE { * version Version, * sid SignerIdentifier, * digestAlgorithm DigestAlgorithmIdentifier, * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, * encryptedDigest EncryptedDigest, * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL * } * * EncryptedDigest ::= OCTET STRING * * DigestAlgorithmIdentifier ::= AlgorithmIdentifier * * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier * * ----------------------------------------- * * RFC 5652: * * SignerInfo ::= SEQUENCE { * version CMSVersion, * sid SignerIdentifier, * digestAlgorithm DigestAlgorithmIdentifier, * signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, * signatureAlgorithm SignatureAlgorithmIdentifier, * signature SignatureValue, * unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL * } * * -- {@link SignerIdentifier} referenced certificates are at containing * -- {@link SignedData} certificates element. * * SignerIdentifier ::= CHOICE { * issuerAndSerialNumber {@link IssuerAndSerialNumber}, * subjectKeyIdentifier [0] SubjectKeyIdentifier } * * -- See {@link Attributes} for generalized SET OF {@link Attribute} * * SignedAttributes ::= SET SIZE (1..MAX) OF Attribute * UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute * * {@link Attribute} ::= SEQUENCE { * attrType OBJECT IDENTIFIER, * attrValues SET OF AttributeValue } * * AttributeValue ::= ANY * * SignatureValue ::= OCTET STRING * </pre> */ public class SignerInfo extends ASN1Object { private ASN1Integer version; private SignerIdentifier sid; private AlgorithmIdentifier digAlgorithm; private ASN1Set authenticatedAttributes; private AlgorithmIdentifier digEncryptionAlgorithm; private ASN1OctetString encryptedDigest; private ASN1Set unauthenticatedAttributes; /** * Return a SignerInfo object from the given input * <p> * Accepted inputs: * <ul> * <li> null → null * <li> {@link SignerInfo} object * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with SignerInfo structure inside * </ul> * * @param o the object we want converted. * @exception IllegalArgumentException if the object cannot be converted. */ public static SignerInfo getInstance(Object o) throws IllegalArgumentException { if (o instanceof SignerInfo) { return (SignerInfo) o; } else if (o != null) { return new SignerInfo(ASN1Sequence.getInstance(o)); } return null; } /** * * @param sid * @param digAlgorithm CMS knows as 'digestAlgorithm' * @param authenticatedAttributes CMS knows as 'signedAttrs' * @param digEncryptionAlgorithm CMS knows as 'signatureAlgorithm' * @param encryptedDigest CMS knows as 'signature' * @param unauthenticatedAttributes CMS knows as 'unsignedAttrs' */ public SignerInfo(SignerIdentifier sid, AlgorithmIdentifier digAlgorithm, ASN1Set authenticatedAttributes, AlgorithmIdentifier digEncryptionAlgorithm, ASN1OctetString encryptedDigest, ASN1Set unauthenticatedAttributes) { if (sid.isTagged()) { this.version = new ASN1Integer(3); } else { this.version = new ASN1Integer(1); } this.sid = sid; this.digAlgorithm = digAlgorithm; this.authenticatedAttributes = authenticatedAttributes; this.digEncryptionAlgorithm = digEncryptionAlgorithm; this.encryptedDigest = encryptedDigest; this.unauthenticatedAttributes = unauthenticatedAttributes; } /** * * @param sid * @param digAlgorithm CMS knows as 'digestAlgorithm' * @param authenticatedAttributes CMS knows as 'signedAttrs' * @param digEncryptionAlgorithm CMS knows as 'signatureAlgorithm' * @param encryptedDigest CMS knows as 'signature' * @param unauthenticatedAttributes CMS knows as 'unsignedAttrs' */ public SignerInfo(SignerIdentifier sid, AlgorithmIdentifier digAlgorithm, Attributes authenticatedAttributes, AlgorithmIdentifier digEncryptionAlgorithm, ASN1OctetString encryptedDigest, Attributes unauthenticatedAttributes) { if (sid.isTagged()) { this.version = new ASN1Integer(3); } else { this.version = new ASN1Integer(1); } this.sid = sid; this.digAlgorithm = digAlgorithm; this.authenticatedAttributes = ASN1Set.getInstance(authenticatedAttributes); this.digEncryptionAlgorithm = digEncryptionAlgorithm; this.encryptedDigest = encryptedDigest; this.unauthenticatedAttributes = ASN1Set.getInstance(unauthenticatedAttributes); } /** * @deprecated use getInstance() method. */ public SignerInfo(ASN1Sequence seq) { Enumeration e = seq.getObjects(); version = (ASN1Integer) e.nextElement(); sid = SignerIdentifier.getInstance(e.nextElement()); digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); Object obj = e.nextElement(); if (obj instanceof ASN1TaggedObject) { authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject) obj, false); digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); } else { authenticatedAttributes = null; digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj); } encryptedDigest = DEROctetString.getInstance(e.nextElement()); if (e.hasMoreElements()) { unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject) e.nextElement(), false); } else { unauthenticatedAttributes = null; } } public ASN1Integer getVersion() { return version; } public SignerIdentifier getSID() { return sid; } public ASN1Set getAuthenticatedAttributes() { return authenticatedAttributes; } public AlgorithmIdentifier getDigestAlgorithm() { return digAlgorithm; } public ASN1OctetString getEncryptedDigest() { return encryptedDigest; } public AlgorithmIdentifier getDigestEncryptionAlgorithm() { return digEncryptionAlgorithm; } public ASN1Set getUnauthenticatedAttributes() { return unauthenticatedAttributes; } /** * Produce an object suitable for an ASN1OutputStream. */ public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(7); v.add(version); v.add(sid); v.add(digAlgorithm); if (authenticatedAttributes != null) { v.add(new DERTaggedObject(false, 0, authenticatedAttributes)); } v.add(digEncryptionAlgorithm); v.add(encryptedDigest); if (unauthenticatedAttributes != null) { v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes)); } return new DERSequence(v); } }