1 /**
2 * Algorithm Identifier
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.asn1.alg_id;
12 
13 import botan.constants;
14 import botan.utils.types;
15 import botan.asn1.asn1_obj;
16 import botan.asn1.asn1_oid;
17 import botan.asn1.der_enc;
18 import botan.asn1.ber_dec;
19 import botan.asn1.oids;
20 
21 alias AlgorithmIdentifier = RefCounted!AlgorithmIdentifierImpl;
22 
23 /**
24 * Algorithm Identifier
25 */
26 final class AlgorithmIdentifierImpl : ASN1Object
27 {
28     version(ARM) {
29         override size_t toHash() const nothrow @safe {
30             return typeid(m_oid).getHash(&m_oid);
31         }
32     } else {
33         
34         override size_t toHash() const nothrow @safe {
35             return typeid(m_oid).getHash(&m_oid);
36         }
37     }
38 public:
39     alias EncodingOption = bool;
40     enum : EncodingOption { USE_NULL_PARAM }
41 
42     /*
43     * DER encode an AlgorithmIdentifier
44     */
45     override void encodeInto(ref DEREncoder codec) const
46     {
47         //logTrace("encoding OID: ", m_oid.toString());
48         codec.startCons(ASN1Tag.SEQUENCE)
49                 .encode(m_oid)
50                 .rawBytes(m_parameters)
51                 .endCons();
52     }
53 
54     /*
55     * Decode a BER encoded AlgorithmIdentifier
56     */
57     override void decodeFrom(ref BERDecoder codec)
58     {
59         codec.startCons(ASN1Tag.SEQUENCE)
60                 .decode(m_oid)
61                 .rawBytes(m_parameters)
62                 .endCons();
63     }
64 
65     this() { m_oid = OID(); }
66 
67     /*
68     * Create an AlgorithmIdentifier
69     */
70     this(OID alg_id, EncodingOption option) {
71         __gshared immutable ubyte[2] DER_NULL = [ 0x05, 0x00 ];
72         
73         m_oid = alg_id;
74         
75         if (option == USE_NULL_PARAM)
76             m_parameters ~= DER_NULL.ptr[0 .. 2];
77     }
78 
79     /*
80     * Create an AlgorithmIdentifier
81     */
82     this(string alg_id, EncodingOption option) {
83         __gshared immutable ubyte[2] DER_NULL = [ 0x05, 0x00 ];
84         
85         m_oid = OIDS.lookup(alg_id);
86         
87         if (option == USE_NULL_PARAM)
88             m_parameters ~= DER_NULL.ptr[0 .. 2];
89     }
90     
91     /*
92     * Create an AlgorithmIdentifier
93     */
94     this(OID alg_id, ref Vector!ubyte param)
95     {
96         m_oid = alg_id;
97         m_parameters = Vector!ubyte(param[]);
98     }
99 
100     /*
101     * Create an AlgorithmIdentifier
102     */
103     this(in string alg_id, ref Vector!ubyte param) {
104         m_oid = OIDS.lookup(alg_id);
105         m_parameters = Vector!ubyte(param[]);
106     }
107 
108     /*
109      * Make a copy of another AlgorithmIdentifier
110      */
111     this(const AlgorithmIdentifierImpl other) {
112         m_oid = OID(other.m_oid);
113         m_parameters = Vector!ubyte(other.m_parameters[]);
114     }
115 
116     /*
117     * Compare two AlgorithmIdentifiers
118     */
119     bool opEquals(in AlgorithmIdentifier a2) const
120     {
121         if (m_oid != a2.m_oid)
122             return false;
123         if (m_parameters != a2.m_parameters)
124             return false;
125         return true;
126     }
127 
128     /*
129     * Compare two AlgorithmIdentifiers
130     */
131     int opCmp(in AlgorithmIdentifier a2) const
132     {
133         if (this == a2) return 0;
134         else return -1;
135     }
136 
137     @property const(OID) oid() const {
138         return m_oid;
139     }
140 
141     @property Vector!ubyte parameters() const {
142         return m_parameters.clone;
143     }
144 
145     @property void oid(OID oid) {
146         m_oid = oid;
147     }
148 
149     @property void parameters()(auto ref Vector!ubyte param) {
150         m_parameters = param.clone;
151     }
152 
153     override string toString() const {
154         return m_oid.toString() ~ " & param length: " ~ m_parameters.length.to!string;
155     }
156 
157 private:
158     OID m_oid;
159     Vector!ubyte m_parameters;
160 }