001package org.apache.commons.ssl.org.bouncycastle.asn1.cms; 002 003import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 004import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer; 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString; 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Set; 010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject; 011import org.apache.commons.ssl.org.bouncycastle.asn1.BERSequence; 012import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject; 013 014/** 015 * <a href="http://tools.ietf.org/html/rfc5083">RFC 5083</a>: 016 * 017 * CMS AuthEnveloped Data object. 018 * <p> 019 * ASN.1: 020 * <pre> 021 * id-ct-authEnvelopedData OBJECT IDENTIFIER ::= { iso(1) 022 * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) 023 * smime(16) ct(1) 23 } 024 * 025 * AuthEnvelopedData ::= SEQUENCE { 026 * version CMSVersion, 027 * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL, 028 * recipientInfos RecipientInfos, 029 * authEncryptedContentInfo EncryptedContentInfo, 030 * authAttrs [1] IMPLICIT AuthAttributes OPTIONAL, 031 * mac MessageAuthenticationCode, 032 * unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL } 033 * </pre> 034 */ 035public class AuthEnvelopedData 036 extends ASN1Object 037{ 038 private ASN1Integer version; 039 private OriginatorInfo originatorInfo; 040 private ASN1Set recipientInfos; 041 private EncryptedContentInfo authEncryptedContentInfo; 042 private ASN1Set authAttrs; 043 private ASN1OctetString mac; 044 private ASN1Set unauthAttrs; 045 046 public AuthEnvelopedData( 047 OriginatorInfo originatorInfo, 048 ASN1Set recipientInfos, 049 EncryptedContentInfo authEncryptedContentInfo, 050 ASN1Set authAttrs, 051 ASN1OctetString mac, 052 ASN1Set unauthAttrs) 053 { 054 // "It MUST be set to 0." 055 this.version = new ASN1Integer(0); 056 057 this.originatorInfo = originatorInfo; 058 059 // TODO 060 // "There MUST be at least one element in the collection." 061 this.recipientInfos = recipientInfos; 062 063 this.authEncryptedContentInfo = authEncryptedContentInfo; 064 065 // TODO 066 // "The authAttrs MUST be present if the content type carried in 067 // EncryptedContentInfo is not id-data." 068 this.authAttrs = authAttrs; 069 070 this.mac = mac; 071 072 this.unauthAttrs = unauthAttrs; 073 } 074 075 /** 076 * Constructs AuthEnvelopedData by parsing supplied ASN1Sequence 077 * <p> 078 * @param seq An ASN1Sequence with AuthEnvelopedData 079 * @deprecated use getInstance(). 080 */ 081 public AuthEnvelopedData( 082 ASN1Sequence seq) 083 { 084 int index = 0; 085 086 // TODO 087 // "It MUST be set to 0." 088 ASN1Primitive tmp = seq.getObjectAt(index++).toASN1Primitive(); 089 version = (ASN1Integer)tmp; 090 091 tmp = seq.getObjectAt(index++).toASN1Primitive(); 092 if (tmp instanceof ASN1TaggedObject) 093 { 094 originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false); 095 tmp = seq.getObjectAt(index++).toASN1Primitive(); 096 } 097 098 // TODO 099 // "There MUST be at least one element in the collection." 100 recipientInfos = ASN1Set.getInstance(tmp); 101 102 tmp = seq.getObjectAt(index++).toASN1Primitive(); 103 authEncryptedContentInfo = EncryptedContentInfo.getInstance(tmp); 104 105 tmp = seq.getObjectAt(index++).toASN1Primitive(); 106 if (tmp instanceof ASN1TaggedObject) 107 { 108 authAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false); 109 tmp = seq.getObjectAt(index++).toASN1Primitive(); 110 } 111 else 112 { 113 // TODO 114 // "The authAttrs MUST be present if the content type carried in 115 // EncryptedContentInfo is not id-data." 116 } 117 118 mac = ASN1OctetString.getInstance(tmp); 119 120 if (seq.size() > index) 121 { 122 tmp = seq.getObjectAt(index++).toASN1Primitive(); 123 unauthAttrs = ASN1Set.getInstance((ASN1TaggedObject)tmp, false); 124 } 125 } 126 127 /** 128 * Return an AuthEnvelopedData object from a tagged object. 129 * <p> 130 * Accepted inputs: 131 * <ul> 132 * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats 133 * </ul> 134 * 135 136 * @param obj the tagged object holding the object we want. 137 * @param explicit true if the object is meant to be explicitly 138 * tagged false otherwise. 139 * @throws IllegalArgumentException if the object held by the 140 * tagged object cannot be converted. 141 */ 142 public static AuthEnvelopedData getInstance( 143 ASN1TaggedObject obj, 144 boolean explicit) 145 { 146 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 147 } 148 149 /** 150 * Return an AuthEnvelopedData object from the given object. 151 * <p> 152 * Accepted inputs: 153 * <ul> 154 * <li> null → null 155 * <li> {@link AuthEnvelopedData} object 156 * <li> {@link ASN1Sequence org.bouncycastle.asn1.ASN1Sequence} input formats with AuthEnvelopedData structure inside 157 * </ul> 158 * 159 * @param obj The object we want converted. 160 * @throws IllegalArgumentException if the object cannot be converted, or was null. 161 */ 162 public static AuthEnvelopedData getInstance( 163 Object obj) 164 { 165 if (obj == null || obj instanceof AuthEnvelopedData) 166 { 167 return (AuthEnvelopedData)obj; 168 } 169 170 if (obj instanceof ASN1Sequence) 171 { 172 return new AuthEnvelopedData((ASN1Sequence)obj); 173 } 174 175 throw new IllegalArgumentException("Invalid AuthEnvelopedData: " + obj.getClass().getName()); 176 } 177 178 public ASN1Integer getVersion() 179 { 180 return version; 181 } 182 183 public OriginatorInfo getOriginatorInfo() 184 { 185 return originatorInfo; 186 } 187 188 public ASN1Set getRecipientInfos() 189 { 190 return recipientInfos; 191 } 192 193 public EncryptedContentInfo getAuthEncryptedContentInfo() 194 { 195 return authEncryptedContentInfo; 196 } 197 198 public ASN1Set getAuthAttrs() 199 { 200 return authAttrs; 201 } 202 203 public ASN1OctetString getMac() 204 { 205 return mac; 206 } 207 208 public ASN1Set getUnauthAttrs() 209 { 210 return unauthAttrs; 211 } 212 213 /** 214 * Produce an object suitable for an ASN1OutputStream. 215 */ 216 public ASN1Primitive toASN1Primitive() 217 { 218 ASN1EncodableVector v = new ASN1EncodableVector(); 219 220 v.add(version); 221 222 if (originatorInfo != null) 223 { 224 v.add(new DERTaggedObject(false, 0, originatorInfo)); 225 } 226 227 v.add(recipientInfos); 228 v.add(authEncryptedContentInfo); 229 230 // "authAttrs optionally contains the authenticated attributes." 231 if (authAttrs != null) 232 { 233 // "AuthAttributes MUST be DER encoded, even if the rest of the 234 // AuthEnvelopedData structure is BER encoded." 235 v.add(new DERTaggedObject(false, 1, authAttrs)); 236 } 237 238 v.add(mac); 239 240 // "unauthAttrs optionally contains the unauthenticated attributes." 241 if (unauthAttrs != null) 242 { 243 v.add(new DERTaggedObject(false, 2, unauthAttrs)); 244 } 245 246 return new BERSequence(v); 247 } 248}