001package org.apache.commons.ssl.org.bouncycastle.asn1.cms; 002 003import java.util.Enumeration; 004 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer; 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Set; 012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject; 013import org.apache.commons.ssl.org.bouncycastle.asn1.DEROctetString; 014import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence; 015import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject; 016import org.apache.commons.ssl.org.bouncycastle.asn1.x509.AlgorithmIdentifier; 017 018/** 019 * <a href="http://tools.ietf.org/html/rfc5652#section-5.3">RFC 5652</a>: 020 * Signature container per Signer, see {@link SignerIdentifier}. 021 * <pre> 022 * PKCS#7: 023 * 024 * SignerInfo ::= SEQUENCE { 025 * version Version, 026 * sid SignerIdentifier, 027 * digestAlgorithm DigestAlgorithmIdentifier, 028 * authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL, 029 * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier, 030 * encryptedDigest EncryptedDigest, 031 * unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL 032 * } 033 * 034 * EncryptedDigest ::= OCTET STRING 035 * 036 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 037 * 038 * DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier 039 * 040 * ----------------------------------------- 041 * 042 * RFC 5256: 043 * 044 * SignerInfo ::= SEQUENCE { 045 * version CMSVersion, 046 * sid SignerIdentifier, 047 * digestAlgorithm DigestAlgorithmIdentifier, 048 * signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, 049 * signatureAlgorithm SignatureAlgorithmIdentifier, 050 * signature SignatureValue, 051 * unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL 052 * } 053 * 054 * -- {@link SignerIdentifier} referenced certificates are at containing 055 * -- {@link SignedData} certificates element. 056 * 057 * SignerIdentifier ::= CHOICE { 058 * issuerAndSerialNumber {@link IssuerAndSerialNumber}, 059 * subjectKeyIdentifier [0] SubjectKeyIdentifier } 060 * 061 * -- See {@link Attributes} for generalized SET OF {@link Attribute} 062 * 063 * SignedAttributes ::= SET SIZE (1..MAX) OF Attribute 064 * UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute 065 * 066 * {@link Attribute} ::= SEQUENCE { 067 * attrType OBJECT IDENTIFIER, 068 * attrValues SET OF AttributeValue } 069 * 070 * AttributeValue ::= ANY 071 * 072 * SignatureValue ::= OCTET STRING 073 * </pre> 074 */ 075public class SignerInfo 076 extends ASN1Object 077{ 078 private ASN1Integer version; 079 private SignerIdentifier sid; 080 private AlgorithmIdentifier digAlgorithm; 081 private ASN1Set authenticatedAttributes; 082 private AlgorithmIdentifier digEncryptionAlgorithm; 083 private ASN1OctetString encryptedDigest; 084 private ASN1Set unauthenticatedAttributes; 085 086 /** 087 * Return a SignerInfo object from the given input 088 * <p> 089 * Accepted inputs: 090 * <ul> 091 * <li> null → null 092 * <li> {@link SignerInfo} object 093 * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with SignerInfo structure inside 094 * </ul> 095 * 096 * @param o the object we want converted. 097 * @exception IllegalArgumentException if the object cannot be converted. 098 */ 099 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}