1 module hunt.security.x509.CertificateVersion;
2 
3 import hunt.security.x509.CertAttrSet;
4 
5 import hunt.security.util.DerInputStream;
6 import hunt.security.util.DerOutputStream;
7 import hunt.security.util.DerValue;
8 
9 import hunt.collection;
10 import hunt.stream.Common;
11 
12 import hunt.Exceptions;
13 import hunt.text.Common;
14 
15 import std.conv;
16 
17 /**
18  * This class defines the version of the X509 Certificate.
19  *
20  * @author Amit Kapoor
21  * @author Hemma Prafullchandra
22  * @see CertAttrSet
23  */
24 class CertificateVersion : CertAttrSet!(string, int)  {
25     /**
26      * X509Certificate Version 1
27      */
28     enum int     V1 = 0;
29     /**
30      * X509Certificate Version 2
31      */
32     enum int     V2 = 1;
33     /**
34      * X509Certificate Version 3
35      */
36     enum int     V3 = 2;
37     /**
38      * Identifier for this attribute, to be used with the
39      * get, set, delete methods of Certificate, x509 type.
40      */
41     enum string IDENT = "x509.info.version";
42     /**
43      * Sub attributes name for this CertAttrSet.
44      */
45     enum string NAME = "version";
46     enum string VERSION = "number";
47 
48     // Private data members
49     int _version = V1;
50 
51     // Returns the version number.
52     private int getVersion() {
53         return(_version);
54     }
55 
56     // Construct the class from the passed DerValue
57     private void construct(DerValue derVal) {
58         // if (derVal.isConstructed() && derVal.isContextSpecific()) {
59         //     derVal = derVal.data.getDerValue();
60         //     _version = derVal.getInteger();
61         //     if (derVal.data.available() != 0) {
62         //         throw new IOException("X.509 version, bad format");
63         //     }
64         // }
65         implementationMissing();
66     }
67 
68     /**
69      * The default constructor for this class,
70      *  sets the version to 0 (i.e. X.509 version 1).
71      */
72     this() {
73         _version = V1;
74     }
75 
76     /**
77      * The constructor for this class for the required version.
78      *
79      * @param version the version for the certificate.
80      * @exception IOException if the version is not valid.
81      */
82     this(int ver) {
83 
84         // check that it is a valid version
85         if (_version == V1 || _version == V2 || _version == V3)
86             this._version = ver;
87         else {
88             throw new IOException("X.509 Certificate version " ~
89                                    ver.to!string() ~ " not supported.\n");
90         }
91     }
92 
93     /**
94      * Create the object, decoding the values from the passed DER stream.
95      *
96      * @param stream the DerInputStream to read the CertificateVersion from.
97      * @exception IOException on decoding errors.
98      */
99     this(DerInputStream stream) {
100         _version = V1;
101         DerValue derVal = stream.getDerValue();
102 
103         construct(derVal);
104     }
105 
106     /**
107      * Create the object, decoding the values from the passed stream.
108      *
109      * @param stream the InputStream to read the CertificateVersion from.
110      * @exception IOException on decoding errors.
111      */
112     this(InputStream stream) {
113         _version = V1;
114         DerValue derVal = new DerValue(stream);
115 
116         construct(derVal);
117     }
118 
119     /**
120      * Create the object, decoding the values from the passed DerValue.
121      *
122      * @param val the Der encoded value.
123      * @exception IOException on decoding errors.
124      */
125     this(DerValue val) {
126         _version = V1;
127 
128         construct(val);
129     }
130 
131     /**
132      * Return the version number of the certificate.
133      */
134     override string toString() {
135         return "Version: V" ~ (_version+1).to!string();
136     }
137 
138     /**
139      * Encode the CertificateVersion period in DER form to the stream.
140      *
141      * @param stream the OutputStream to marshal the contents to.
142      * @exception IOException on errors.
143      */
144     void encode(OutputStream stream) {
145         // Nothing for default
146         if (_version == V1) {
147             return;
148         }
149         DerOutputStream tmp = new DerOutputStream();
150         tmp.putInteger(_version);
151 
152         DerOutputStream seq = new DerOutputStream();
153         seq.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, cast(byte)0),
154                   tmp);
155 
156         stream.write(seq.toByteArray());
157     }
158 
159     /**
160      * Set the attribute value.
161      */
162     void set(string name, int obj) {
163         implementationMissing();
164         // if (!(obj instanceof int)) {
165         //     throw new IOException("Attribute must be of type int.");
166         // }
167         // if (name.equalsIgnoreCase(VERSION)) {
168         //     _version = ((int)obj).intValue();
169         // } else {
170         //     throw new IOException("Attribute name not recognized by " ~
171         //                           "CertAttrSet: CertificateVersion.");
172         // }
173     }
174 
175     /**
176      * Get the attribute value.
177      */
178     int get(string name) {
179         if (name.equalsIgnoreCase(VERSION)) {
180             return(getVersion());
181         } else {
182             throw new IOException("Attribute name not recognized by " ~
183                                   "CertAttrSet: CertificateVersion.");
184         }
185     }
186 
187     /**
188      * Delete the attribute value.
189      */
190     void remove(string name) {
191         if (name.equalsIgnoreCase(VERSION)) {
192             _version = V1;
193         } else {
194             throw new IOException("Attribute name not recognized by " ~
195                                   "CertAttrSet: CertificateVersion.");
196         }
197     }
198 
199     /**
200      * Return an enumeration of names of attributes existing within this
201      * attribute.
202      */
203     Enumeration!string getElements() {
204         // AttributeNameEnumeration elements = new AttributeNameEnumeration();
205         // elements.addElement(VERSION);
206 
207         // return (elements.elements());
208                 implementationMissing();
209         return null;
210 
211     }
212 
213     /**
214      * Return the name of this attribute.
215      */
216     string getName() {
217         return(NAME);
218     }
219 
220     /**
221      * Compare versions.
222      */
223     int compare(int vers) {
224         return(_version - vers);
225     }
226 }