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 }