SignerInfo.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
1package org.bouncycastle.asn1.cms; 2 3import java.util.Enumeration; 4 5import org.bouncycastle.asn1.ASN1EncodableVector; 6import org.bouncycastle.asn1.ASN1Integer; 7import org.bouncycastle.asn1.ASN1Object; 8import org.bouncycastle.asn1.ASN1OctetString; 9import org.bouncycastle.asn1.ASN1Primitive; 10import org.bouncycastle.asn1.ASN1Sequence; 11import org.bouncycastle.asn1.ASN1Set; 12import org.bouncycastle.asn1.ASN1TaggedObject; 13import org.bouncycastle.asn1.DEROctetString; 14import org.bouncycastle.asn1.DERSequence; 15import org.bouncycastle.asn1.DERTaggedObject; 16import 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 5256: 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 */ 75public 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 */ 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 */ 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 */ 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 */ 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 221 public ASN1Integer getVersion() 222 { 223 return version; 224 } 225 226 public SignerIdentifier getSID() 227 { 228 return sid; 229 } 230 231 public ASN1Set getAuthenticatedAttributes() 232 { 233 return authenticatedAttributes; 234 } 235 236 public AlgorithmIdentifier getDigestAlgorithm() 237 { 238 return digAlgorithm; 239 } 240 241 public ASN1OctetString getEncryptedDigest() 242 { 243 return encryptedDigest; 244 } 245 246 public AlgorithmIdentifier getDigestEncryptionAlgorithm() 247 { 248 return digEncryptionAlgorithm; 249 } 250 251 public ASN1Set getUnauthenticatedAttributes() 252 { 253 return unauthenticatedAttributes; 254 } 255 256 /** 257 * Produce an object suitable for an ASN1OutputStream. 258 */ 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