1 package org.bouncycastle.asn1.x509; 2 3 import java.util.Enumeration; 4 import java.util.Hashtable; 5 import java.util.Vector; 6 7 import org.bouncycastle.asn1.ASN1Encodable; 8 import org.bouncycastle.asn1.ASN1EncodableVector; 9 import org.bouncycastle.asn1.ASN1Object; 10 import org.bouncycastle.asn1.ASN1ObjectIdentifier; 11 import org.bouncycastle.asn1.ASN1Primitive; 12 import org.bouncycastle.asn1.ASN1Sequence; 13 import org.bouncycastle.asn1.ASN1TaggedObject; 14 import org.bouncycastle.asn1.DERSequence; 15 16 /** 17 * The extendedKeyUsage object. 18 * <pre> 19 * extendedKeyUsage ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId 20 * </pre> 21 */ 22 public class ExtendedKeyUsage 23 extends ASN1Object 24 { 25 Hashtable usageTable = new Hashtable(); 26 ASN1Sequence seq; 27 28 /** 29 * Return an ExtendedKeyUsage from the passed in tagged object. 30 * 31 * @param obj the tagged object containing the ExtendedKeyUsage 32 * @param explicit true if the tagged object should be interpreted as explicitly tagged, false if implicit. 33 * @return the ExtendedKeyUsage contained. 34 */ 35 public static ExtendedKeyUsage getInstance( 36 ASN1TaggedObject obj, 37 boolean explicit) 38 { 39 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 40 } 41 42 /** 43 * Return an ExtendedKeyUsage from the passed in object. 44 * 45 * @param obj an ExtendedKeyUsage, some form or encoding of one, or null. 46 * @return an ExtendedKeyUsage object, or null if null is passed in. 47 */ 48 public static ExtendedKeyUsage getInstance( 49 Object obj) 50 { 51 if (obj instanceof ExtendedKeyUsage) 52 { 53 return (ExtendedKeyUsage)obj; 54 } 55 else if (obj != null) 56 { 57 return new ExtendedKeyUsage(ASN1Sequence.getInstance(obj)); 58 } 59 60 return null; 61 } 62 63 /** 64 * Retrieve an ExtendedKeyUsage for a passed in Extensions object, if present. 65 * 66 * @param extensions the extensions object to be examined. 67 * @return the ExtendedKeyUsage, null if the extension is not present. 68 */ 69 public static ExtendedKeyUsage fromExtensions(Extensions extensions) 70 { 71 return ExtendedKeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.extendedKeyUsage)); 72 } 73 74 /** 75 * Base constructor, from a single KeyPurposeId. 76 * 77 * @param usage the keyPurposeId to be included. 78 */ 79 public ExtendedKeyUsage( 80 KeyPurposeId usage) 81 { 82 this.seq = new DERSequence(usage); 83 84 this.usageTable.put(usage, usage); 85 } 86 87 private ExtendedKeyUsage( 88 ASN1Sequence seq) 89 { 90 this.seq = seq; 91 92 Enumeration e = seq.getObjects(); 93 94 while (e.hasMoreElements()) 95 { 96 ASN1Encodable o = (ASN1Encodable)e.nextElement(); 97 if (!(o.toASN1Primitive() instanceof ASN1ObjectIdentifier)) 98 { 99 throw new IllegalArgumentException("Only ASN1ObjectIdentifiers allowed in ExtendedKeyUsage."); 100 } 101 this.usageTable.put(o, o); 102 } 103 } 104 105 /** 106 * Base constructor, from multiple KeyPurposeIds. 107 * 108 * @param usages an array of KeyPurposeIds. 109 */ 110 public ExtendedKeyUsage( 111 KeyPurposeId[] usages) 112 { 113 ASN1EncodableVector v = new ASN1EncodableVector(); 114 115 for (int i = 0; i != usages.length; i++) 116 { 117 v.add(usages[i]); 118 this.usageTable.put(usages[i], usages[i]); 119 } 120 121 this.seq = new DERSequence(v); 122 } 123 124 /** 125 * @deprecated use KeyPurposeId[] constructor. 126 */ 127 public ExtendedKeyUsage( 128 Vector usages) 129 { 130 ASN1EncodableVector v = new ASN1EncodableVector(); 131 Enumeration e = usages.elements(); 132 133 while (e.hasMoreElements()) 134 { 135 KeyPurposeId o = KeyPurposeId.getInstance(e.nextElement()); 136 137 v.add(o); 138 this.usageTable.put(o, o); 139 } 140 141 this.seq = new DERSequence(v); 142 } 143 144 /** 145 * Return true if this ExtendedKeyUsage object contains the passed in keyPurposeId. 146 * 147 * @param keyPurposeId the KeyPurposeId of interest. 148 * @return true if the keyPurposeId is present, false otherwise. 149 */ 150 public boolean hasKeyPurposeId( 151 KeyPurposeId keyPurposeId) 152 { 153 return (usageTable.get(keyPurposeId) != null); 154 } 155 156 /** 157 * Returns all extended key usages. 158 * 159 * @return An array with all key purposes. 160 */ 161 public KeyPurposeId[] getUsages() 162 { 163 KeyPurposeId[] temp = new KeyPurposeId[seq.size()]; 164 165 int i = 0; 166 for (Enumeration it = seq.getObjects(); it.hasMoreElements();) 167 { 168 temp[i++] = KeyPurposeId.getInstance(it.nextElement()); 169 } 170 return temp; 171 } 172 173 /** 174 * Return the number of KeyPurposeIds present in this ExtendedKeyUsage. 175 * 176 * @return the number of KeyPurposeIds 177 */ 178 public int size() 179 { 180 return usageTable.size(); 181 } 182 183 /** 184 * Return the ASN.1 primitive form of this object. 185 * 186 * @return an ASN1Sequence. 187 */ 188 public ASN1Primitive toASN1Primitive() 189 { 190 return seq; 191 } 192 } 193