1 /** 2 * Enumerations 3 * 4 * Copyright: 5 * (C) 1999-2007 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.cert.x509.key_constraint; 12 13 import botan.constants; 14 //static if (BOTAN_HAS_X509_CERTIFICATES): 15 16 import botan.asn1.ber_dec; 17 import botan.pubkey.x509_key; 18 import botan.pubkey.pk_keys; 19 import botan.asn1.ber_dec; 20 21 /** 22 * X.509v3 Key Constraints. 23 */ 24 enum KeyConstraints { 25 NO_CONSTRAINTS = 0, 26 DIGITAL_SIGNATURE = 32768, 27 NON_REPUDIATION = 16384, 28 KEY_ENCIPHERMENT = 8192, 29 DATA_ENCIPHERMENT = 4096, 30 KEY_AGREEMENT = 2048, 31 KEY_CERT_SIGN = 1024, 32 CRL_SIGN = 512, 33 ENCIPHER_ONLY = 256, 34 DECIPHER_ONLY = 128 35 } 36 37 /** 38 * Create the key constraints for a specific public key. 39 * Params: 40 * pub_key = the public key from which the basic set of 41 * constraints to be placed in the return value is derived 42 * limits = additional limits that will be incorporated into the 43 * return value 44 * Returns: combination of key type specific constraints and 45 * additional limits 46 */ 47 KeyConstraints findConstraints(in PublicKey pub_key, 48 KeyConstraints limits) 49 { 50 const string name = pub_key.algoName; 51 52 KeyConstraints constraints; 53 54 if (name == "DH" || name == "ECDH") 55 constraints |= KeyConstraints.KEY_AGREEMENT; 56 57 if (name == "RSA" || name == "ElGamal") 58 constraints |= KeyConstraints.KEY_ENCIPHERMENT | KeyConstraints.DATA_ENCIPHERMENT; 59 60 if (name == "RSA" || name == "RW" || name == "NR" || 61 name == "DSA" || name == "ECDSA") 62 constraints |= KeyConstraints.DIGITAL_SIGNATURE | KeyConstraints.NON_REPUDIATION; 63 64 if (limits) 65 constraints &= limits; 66 67 return constraints; 68 } 69 70 /* 71 * Decode a BER encoded KeyUsage 72 */ 73 void decode(BERDecoder source, ref KeyConstraints key_usage) 74 { 75 BERObject obj = source.getNextObject(); 76 77 if (obj.type_tag != ASN1Tag.BIT_STRING || obj.class_tag != ASN1Tag.UNIVERSAL) 78 throw new BERBadTag("Bad tag for usage constraint", 79 obj.type_tag, obj.class_tag); 80 if (obj.value.length != 2 && obj.value.length != 3) 81 throw new BERDecodingError("Bad size for BITSTRING in usage constraint"); 82 if (obj.value[0] >= 8) 83 throw new BERDecodingError("Invalid unused bits in usage constraint"); 84 85 const ubyte mask = cast(const ubyte)(0xFF << obj.value[0]); 86 obj.value[obj.value.length-1] &= mask; 87 88 KeyConstraints usage; 89 for (size_t j = 1; j != obj.value.length; ++j) 90 usage |= cast(KeyConstraints)(obj.value[j] << 8); 91 92 key_usage = usage; 93 }