001package org.apache.commons.ssl.org.bouncycastle.asn1.cms; 002 003import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Choice; 004import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable; 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 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.ASN1TaggedObject; 010import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject; 011 012/** 013 * <a href="http://tools.ietf.org/html/rfc5652#section-6.2">RFC 5652</a>: 014 * Content encryption key delivery mechanisms. 015 * <p> 016 * <pre> 017 * RecipientInfo ::= CHOICE { 018 * ktri KeyTransRecipientInfo, 019 * kari [1] KeyAgreeRecipientInfo, 020 * kekri [2] KEKRecipientInfo, 021 * pwri [3] PasswordRecipientInfo, 022 * ori [4] OtherRecipientInfo } 023 * </pre> 024 */ 025public class RecipientInfo 026 extends ASN1Object 027 implements ASN1Choice 028{ 029 ASN1Encodable info; 030 031 public RecipientInfo( 032 KeyTransRecipientInfo info) 033 { 034 this.info = info; 035 } 036 037 public RecipientInfo( 038 KeyAgreeRecipientInfo info) 039 { 040 this.info = new DERTaggedObject(false, 1, info); 041 } 042 043 public RecipientInfo( 044 KEKRecipientInfo info) 045 { 046 this.info = new DERTaggedObject(false, 2, info); 047 } 048 049 public RecipientInfo( 050 PasswordRecipientInfo info) 051 { 052 this.info = new DERTaggedObject(false, 3, info); 053 } 054 055 public RecipientInfo( 056 OtherRecipientInfo info) 057 { 058 this.info = new DERTaggedObject(false, 4, info); 059 } 060 061 public RecipientInfo( 062 ASN1Primitive info) 063 { 064 this.info = info; 065 } 066 067 /** 068 * Return a RecipientInfo object from the given object. 069 * <p> 070 * Accepted inputs: 071 * <ul> 072 * <li> null → null 073 * <li> {@link RecipientInfo} object 074 * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with RecipientInfo structure inside 075 * <li> {@link org.bouncycastle.asn1.ASN1TaggedObject#getInstance(java.lang.Object) ASN1TaggedObject} input formats with RecipientInfo structure inside 076 * </ul> 077 * 078 * @param o the object we want converted. 079 * @exception IllegalArgumentException if the object cannot be converted. 080 */ 081 public static RecipientInfo getInstance( 082 Object o) 083 { 084 if (o == null || o instanceof RecipientInfo) 085 { 086 return (RecipientInfo)o; 087 } 088 else if (o instanceof ASN1Sequence) 089 { 090 return new RecipientInfo((ASN1Sequence)o); 091 } 092 else if (o instanceof ASN1TaggedObject) 093 { 094 return new RecipientInfo((ASN1TaggedObject)o); 095 } 096 097 throw new IllegalArgumentException("unknown object in factory: " 098 + o.getClass().getName()); 099 } 100 101 public ASN1Integer getVersion() 102 { 103 if (info instanceof ASN1TaggedObject) 104 { 105 ASN1TaggedObject o = (ASN1TaggedObject)info; 106 107 switch (o.getTagNo()) 108 { 109 case 1: 110 return KeyAgreeRecipientInfo.getInstance(o, false).getVersion(); 111 case 2: 112 return getKEKInfo(o).getVersion(); 113 case 3: 114 return PasswordRecipientInfo.getInstance(o, false).getVersion(); 115 case 4: 116 return new ASN1Integer(0); // no syntax version for OtherRecipientInfo 117 default: 118 throw new IllegalStateException("unknown tag"); 119 } 120 } 121 122 return KeyTransRecipientInfo.getInstance(info).getVersion(); 123 } 124 125 public boolean isTagged() 126 { 127 return (info instanceof ASN1TaggedObject); 128 } 129 130 public ASN1Encodable getInfo() 131 { 132 if (info instanceof ASN1TaggedObject) 133 { 134 ASN1TaggedObject o = (ASN1TaggedObject)info; 135 136 switch (o.getTagNo()) 137 { 138 case 1: 139 return KeyAgreeRecipientInfo.getInstance(o, false); 140 case 2: 141 return getKEKInfo(o); 142 case 3: 143 return PasswordRecipientInfo.getInstance(o, false); 144 case 4: 145 return OtherRecipientInfo.getInstance(o, false); 146 default: 147 throw new IllegalStateException("unknown tag"); 148 } 149 } 150 151 return KeyTransRecipientInfo.getInstance(info); 152 } 153 154 private KEKRecipientInfo getKEKInfo(ASN1TaggedObject o) 155 { 156 if (o.isExplicit()) 157 { // compatibilty with erroneous version 158 return KEKRecipientInfo.getInstance(o, true); 159 } 160 else 161 { 162 return KEKRecipientInfo.getInstance(o, false); 163 } 164 } 165 166 /** 167 * Produce an object suitable for an ASN1OutputStream. 168 */ 169 public ASN1Primitive toASN1Primitive() 170 { 171 return info.toASN1Primitive(); 172 } 173}