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