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.ASN1Primitive; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Set; 011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject; 012import org.apache.commons.ssl.org.bouncycastle.asn1.BERSequence; 013import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject; 014 015/** 016 * <a href="http://tools.ietf.org/html/rfc5652#section-6.1">RFC 5652</a> EnvelopedData object. 017 * <pre> 018 * EnvelopedData ::= SEQUENCE { 019 * version CMSVersion, 020 * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL, 021 * recipientInfos RecipientInfos, 022 * encryptedContentInfo EncryptedContentInfo, 023 * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL 024 * } 025 * </pre> 026 */ 027public class EnvelopedData 028 extends ASN1Object 029{ 030 private ASN1Integer version; 031 private OriginatorInfo originatorInfo; 032 private ASN1Set recipientInfos; 033 private EncryptedContentInfo encryptedContentInfo; 034 private ASN1Set unprotectedAttrs; 035 036 public EnvelopedData( 037 OriginatorInfo originatorInfo, 038 ASN1Set recipientInfos, 039 EncryptedContentInfo encryptedContentInfo, 040 ASN1Set unprotectedAttrs) 041 { 042 version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, unprotectedAttrs)); 043 044 this.originatorInfo = originatorInfo; 045 this.recipientInfos = recipientInfos; 046 this.encryptedContentInfo = encryptedContentInfo; 047 this.unprotectedAttrs = unprotectedAttrs; 048 } 049 050 public EnvelopedData( 051 OriginatorInfo originatorInfo, 052 ASN1Set recipientInfos, 053 EncryptedContentInfo encryptedContentInfo, 054 Attributes unprotectedAttrs) 055 { 056 version = new ASN1Integer(calculateVersion(originatorInfo, recipientInfos, ASN1Set.getInstance(unprotectedAttrs))); 057 058 this.originatorInfo = originatorInfo; 059 this.recipientInfos = recipientInfos; 060 this.encryptedContentInfo = encryptedContentInfo; 061 this.unprotectedAttrs = ASN1Set.getInstance(unprotectedAttrs); 062 } 063 064 /** 065 * @deprecated use getInstance() 066 */ 067 public EnvelopedData( 068 ASN1Sequence seq) 069 { 070 int index = 0; 071 072 version = (ASN1Integer)seq.getObjectAt(index++); 073 074 Object tmp = seq.getObjectAt(index++); 075 076 if (tmp instanceof ASN1TaggedObject) 077 { 078 originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false); 079 tmp = seq.getObjectAt(index++); 080 } 081 082 recipientInfos = ASN1Set.getInstance(tmp); 083 084 encryptedContentInfo = EncryptedContentInfo.getInstance(seq.getObjectAt(index++)); 085 086 if(seq.size() > index) 087 { 088 unprotectedAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false); 089 } 090 } 091 092 /** 093 * Return an EnvelopedData object from a tagged object. 094 * 095 * @param obj the tagged object holding the object we want. 096 * @param explicit true if the object is meant to be explicitly 097 * tagged false otherwise. 098 * @exception IllegalArgumentException if the object held by the 099 * tagged object cannot be converted. 100 */ 101 public static EnvelopedData getInstance( 102 ASN1TaggedObject obj, 103 boolean explicit) 104 { 105 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 106 } 107 108 /** 109 * Return an EnvelopedData object from the given object. 110 * <p> 111 * Accepted inputs: 112 * <ul> 113 * <li> null → null 114 * <li> {@link EnvelopedData} object 115 * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with EnvelopedData structure inside 116 * </ul> 117 * 118 * @param obj the object we want converted. 119 * @exception IllegalArgumentException if the object cannot be converted. 120 */ 121 public static EnvelopedData getInstance( 122 Object obj) 123 { 124 if (obj instanceof EnvelopedData) 125 { 126 return (EnvelopedData)obj; 127 } 128 129 if (obj != null) 130 { 131 return new EnvelopedData(ASN1Sequence.getInstance(obj)); 132 } 133 134 return null; 135 } 136 137 public ASN1Integer getVersion() 138 { 139 return version; 140 } 141 142 public OriginatorInfo getOriginatorInfo() 143 { 144 return originatorInfo; 145 } 146 147 public ASN1Set getRecipientInfos() 148 { 149 return recipientInfos; 150 } 151 152 public EncryptedContentInfo getEncryptedContentInfo() 153 { 154 return encryptedContentInfo; 155 } 156 157 public ASN1Set getUnprotectedAttrs() 158 { 159 return unprotectedAttrs; 160 } 161 162 /** 163 * Produce an object suitable for an ASN1OutputStream. 164 */ 165 public ASN1Primitive toASN1Primitive() 166 { 167 ASN1EncodableVector v = new ASN1EncodableVector(); 168 169 v.add(version); 170 171 if (originatorInfo != null) 172 { 173 v.add(new DERTaggedObject(false, 0, originatorInfo)); 174 } 175 176 v.add(recipientInfos); 177 v.add(encryptedContentInfo); 178 179 if (unprotectedAttrs != null) 180 { 181 v.add(new DERTaggedObject(false, 1, unprotectedAttrs)); 182 } 183 184 return new BERSequence(v); 185 } 186 187 public static int calculateVersion(OriginatorInfo originatorInfo, ASN1Set recipientInfos, ASN1Set unprotectedAttrs) 188 { 189 int version; 190 191 if (originatorInfo != null || unprotectedAttrs != null) 192 { 193 version = 2; 194 } 195 else 196 { 197 version = 0; 198 199 Enumeration e = recipientInfos.getObjects(); 200 201 while (e.hasMoreElements()) 202 { 203 RecipientInfo ri = RecipientInfo.getInstance(e.nextElement()); 204 205 if (ri.getVersion().getValue().intValue() != version) 206 { 207 version = 2; 208 break; 209 } 210 } 211 } 212 213 return version; 214 } 215}