001package org.apache.commons.ssl.org.bouncycastle.asn1.x509; 002 003import java.util.Enumeration; 004import java.util.Hashtable; 005import java.util.Vector; 006 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1ObjectIdentifier; 011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 013import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject; 014import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence; 015 016/** 017 * The extendedKeyUsage object. 018 * <pre> 019 * extendedKeyUsage ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId 020 * </pre> 021 */ 022public class ExtendedKeyUsage 023 extends ASN1Object 024{ 025 Hashtable usageTable = new Hashtable(); 026 ASN1Sequence seq; 027 028 /** 029 * Return an ExtendedKeyUsage from the passed in tagged object. 030 * 031 * @param obj the tagged object containing the ExtendedKeyUsage 032 * @param explicit true if the tagged object should be interpreted as explicitly tagged, false if implicit. 033 * @return the ExtendedKeyUsage contained. 034 */ 035 public static ExtendedKeyUsage getInstance( 036 ASN1TaggedObject obj, 037 boolean explicit) 038 { 039 return getInstance(ASN1Sequence.getInstance(obj, explicit)); 040 } 041 042 /** 043 * Return an ExtendedKeyUsage from the passed in object. 044 * 045 * @param obj an ExtendedKeyUsage, some form or encoding of one, or null. 046 * @return an ExtendedKeyUsage object, or null if null is passed in. 047 */ 048 public static ExtendedKeyUsage getInstance( 049 Object obj) 050 { 051 if (obj instanceof ExtendedKeyUsage) 052 { 053 return (ExtendedKeyUsage)obj; 054 } 055 else if (obj != null) 056 { 057 return new ExtendedKeyUsage(ASN1Sequence.getInstance(obj)); 058 } 059 060 return null; 061 } 062 063 /** 064 * Retrieve an ExtendedKeyUsage for a passed in Extensions object, if present. 065 * 066 * @param extensions the extensions object to be examined. 067 * @return the ExtendedKeyUsage, null if the extension is not present. 068 */ 069 public static ExtendedKeyUsage fromExtensions(Extensions extensions) 070 { 071 return ExtendedKeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.extendedKeyUsage)); 072 } 073 074 /** 075 * Base constructor, from a single KeyPurposeId. 076 * 077 * @param usage the keyPurposeId to be included. 078 */ 079 public ExtendedKeyUsage( 080 KeyPurposeId usage) 081 { 082 this.seq = new DERSequence(usage); 083 084 this.usageTable.put(usage, usage); 085 } 086 087 private ExtendedKeyUsage( 088 ASN1Sequence seq) 089 { 090 this.seq = seq; 091 092 Enumeration e = seq.getObjects(); 093 094 while (e.hasMoreElements()) 095 { 096 ASN1Encodable o = (ASN1Encodable)e.nextElement(); 097 if (!(o.toASN1Primitive() instanceof ASN1ObjectIdentifier)) 098 { 099 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}