1 package org.bouncycastle.asn1.cms; 2 3 import java.util.Enumeration; 4 5 import org.bouncycastle.asn1.ASN1EncodableVector; 6 import org.bouncycastle.asn1.ASN1Integer; 7 import org.bouncycastle.asn1.ASN1Object; 8 import org.bouncycastle.asn1.ASN1OctetString; 9 import org.bouncycastle.asn1.ASN1Primitive; 10 import org.bouncycastle.asn1.ASN1Sequence; 11 import org.bouncycastle.asn1.ASN1Set; 12 import org.bouncycastle.asn1.ASN1TaggedObject; 13 import org.bouncycastle.asn1.DEROctetString; 14 import org.bouncycastle.asn1.DERSequence; 15 import org.bouncycastle.asn1.DERTaggedObject; 16 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 17 18 /** 19 * <a href="http://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>: 20 * Signature container per Signer, see {@link SignerIdentifier}. 21 * <pre> 22 * PKCS#7: 23 * 24 * SignerInfo ::= SEQUENCE { 25 * version Version, 26 * sid SignerIdentifier, 27 * digestAlgorithm DigestAlgorithmIdentifier, 28 * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, 29 * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, 30 * encryptedDigest EncryptedDigest, 31 * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL 32 * } 33 * 34 * EncryptedDigest ::= OCTET STRING 35 * 36 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 37 * 38 * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier 39 * 40 * ----------------------------------------- 41 * 42 * RFC 5652: 43 * 44 * SignerInfo ::= SEQUENCE { 45 * version CMSVersion, 46 * sid SignerIdentifier, 47 * digestAlgorithm DigestAlgorithmIdentifier, 48 * signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, 49 * signatureAlgorithm SignatureAlgorithmIdentifier, 50 * signature SignatureValue, 51 * unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL 52 * } 53 * 54 * -- {@link SignerIdentifier} referenced certificates are at containing 55 * -- {@link SignedData} certificates element. 56 * 57 * SignerIdentifier ::= CHOICE { 58 * issuerAndSerialNumber {@link IssuerAndSerialNumber}, 59 * subjectKeyIdentifier [0] SubjectKeyIdentifier } 60 * 61 * -- See {@link Attributes} for generalized SET OF {@link Attribute} 62 * 63 * SignedAttributes ::= SET SIZE (1..MAX) OF Attribute 64 * UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute 65 * 66 * {@link Attribute} ::= SEQUENCE { 67 * attrType OBJECT IDENTIFIER, 68 * attrValues SET OF AttributeValue } 69 * 70 * AttributeValue ::= ANY 71 * 72 * SignatureValue ::= OCTET STRING 73 * </pre> 74 */ 75 public class SignerInfo 76 extends ASN1Object 77 { 78 private ASN1Integer version; 79 private SignerIdentifier sid; 80 private AlgorithmIdentifier digAlgorithm; 81 private ASN1Set authenticatedAttributes; 82 private AlgorithmIdentifier digEncryptionAlgorithm; 83 private ASN1OctetString encryptedDigest; 84 private ASN1Set unauthenticatedAttributes; 85 86 /** 87 * Return a SignerInfo object from the given input 88 * <p> 89 * Accepted inputs: 90 * <ul> 91 * <li> null → null 92 * <li> {@link SignerInfo} object 93 * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with SignerInfo structure inside 94 * </ul> 95 * 96 * @param o the object we want converted. 97 * @exception IllegalArgumentException if the object cannot be converted. 98 */ getInstance( Object o)99 public static SignerInfo getInstance( 100 Object o) 101 throws IllegalArgumentException 102 { 103 if (o instanceof SignerInfo) 104 { 105 return (SignerInfo)o; 106 } 107 else if (o != null) 108 { 109 return new SignerInfo(ASN1Sequence.getInstance(o)); 110 } 111 112 return null; 113 } 114 115 /** 116 * 117 * @param sid 118 * @param digAlgorithm CMS knows as 'digestAlgorithm' 119 * @param authenticatedAttributes CMS knows as 'signedAttrs' 120 * @param digEncryptionAlgorithm CMS knows as 'signatureAlgorithm' 121 * @param encryptedDigest CMS knows as 'signature' 122 * @param unauthenticatedAttributes CMS knows as 'unsignedAttrs' 123 */ SignerInfo( SignerIdentifier sid, AlgorithmIdentifier digAlgorithm, ASN1Set authenticatedAttributes, AlgorithmIdentifier digEncryptionAlgorithm, ASN1OctetString encryptedDigest, ASN1Set unauthenticatedAttributes)124 public SignerInfo( 125 SignerIdentifier sid, 126 AlgorithmIdentifier digAlgorithm, 127 ASN1Set authenticatedAttributes, 128 AlgorithmIdentifier digEncryptionAlgorithm, 129 ASN1OctetString encryptedDigest, 130 ASN1Set unauthenticatedAttributes) 131 { 132 if (sid.isTagged()) 133 { 134 this.version = new ASN1Integer(3); 135 } 136 else 137 { 138 this.version = new ASN1Integer(1); 139 } 140 141 this.sid = sid; 142 this.digAlgorithm = digAlgorithm; 143 this.authenticatedAttributes = authenticatedAttributes; 144 this.digEncryptionAlgorithm = digEncryptionAlgorithm; 145 this.encryptedDigest = encryptedDigest; 146 this.unauthenticatedAttributes = unauthenticatedAttributes; 147 } 148 149 /** 150 * 151 * @param sid 152 * @param digAlgorithm CMS knows as 'digestAlgorithm' 153 * @param authenticatedAttributes CMS knows as 'signedAttrs' 154 * @param digEncryptionAlgorithm CMS knows as 'signatureAlgorithm' 155 * @param encryptedDigest CMS knows as 'signature' 156 * @param unauthenticatedAttributes CMS knows as 'unsignedAttrs' 157 */ SignerInfo( SignerIdentifier sid, AlgorithmIdentifier digAlgorithm, Attributes authenticatedAttributes, AlgorithmIdentifier digEncryptionAlgorithm, ASN1OctetString encryptedDigest, Attributes unauthenticatedAttributes)158 public SignerInfo( 159 SignerIdentifier sid, 160 AlgorithmIdentifier digAlgorithm, 161 Attributes authenticatedAttributes, 162 AlgorithmIdentifier digEncryptionAlgorithm, 163 ASN1OctetString encryptedDigest, 164 Attributes unauthenticatedAttributes) 165 { 166 if (sid.isTagged()) 167 { 168 this.version = new ASN1Integer(3); 169 } 170 else 171 { 172 this.version = new ASN1Integer(1); 173 } 174 175 this.sid = sid; 176 this.digAlgorithm = digAlgorithm; 177 this.authenticatedAttributes = ASN1Set.getInstance(authenticatedAttributes); 178 this.digEncryptionAlgorithm = digEncryptionAlgorithm; 179 this.encryptedDigest = encryptedDigest; 180 this.unauthenticatedAttributes = ASN1Set.getInstance(unauthenticatedAttributes); 181 } 182 183 /** 184 * @deprecated use getInstance() method. 185 */ SignerInfo( ASN1Sequence seq)186 public SignerInfo( 187 ASN1Sequence seq) 188 { 189 Enumeration e = seq.getObjects(); 190 191 version = (ASN1Integer)e.nextElement(); 192 sid = SignerIdentifier.getInstance(e.nextElement()); 193 digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); 194 195 Object obj = e.nextElement(); 196 197 if (obj instanceof ASN1TaggedObject) 198 { 199 authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)obj, false); 200 201 digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); 202 } 203 else 204 { 205 authenticatedAttributes = null; 206 digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj); 207 } 208 209 encryptedDigest = DEROctetString.getInstance(e.nextElement()); 210 211 if (e.hasMoreElements()) 212 { 213 unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false); 214 } 215 else 216 { 217 unauthenticatedAttributes = null; 218 } 219 } 220 getVersion()221 public ASN1Integer getVersion() 222 { 223 return version; 224 } 225 getSID()226 public SignerIdentifier getSID() 227 { 228 return sid; 229 } 230 getAuthenticatedAttributes()231 public ASN1Set getAuthenticatedAttributes() 232 { 233 return authenticatedAttributes; 234 } 235 getDigestAlgorithm()236 public AlgorithmIdentifier getDigestAlgorithm() 237 { 238 return digAlgorithm; 239 } 240 getEncryptedDigest()241 public ASN1OctetString getEncryptedDigest() 242 { 243 return encryptedDigest; 244 } 245 getDigestEncryptionAlgorithm()246 public AlgorithmIdentifier getDigestEncryptionAlgorithm() 247 { 248 return digEncryptionAlgorithm; 249 } 250 getUnauthenticatedAttributes()251 public ASN1Set getUnauthenticatedAttributes() 252 { 253 return unauthenticatedAttributes; 254 } 255 256 /** 257 * Produce an object suitable for an ASN1OutputStream. 258 */ toASN1Primitive()259 public ASN1Primitive toASN1Primitive() 260 { 261 ASN1EncodableVector v = new ASN1EncodableVector(); 262 263 v.add(version); 264 v.add(sid); 265 v.add(digAlgorithm); 266 267 if (authenticatedAttributes != null) 268 { 269 v.add(new DERTaggedObject(false, 0, authenticatedAttributes)); 270 } 271 272 v.add(digEncryptionAlgorithm); 273 v.add(encryptedDigest); 274 275 if (unauthenticatedAttributes != null) 276 { 277 v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes)); 278 } 279 280 return new DERSequence(v); 281 } 282 } 283