1 module hunt.security.cert.Certificate;
2 
3 import hunt.security.Key;
4 import hunt.security.Provider;
5 
6 import hunt.Exceptions;
7 
8 /**
9  * <p>Abstract class for managing a variety of identity certificates.
10  * An identity certificate is a binding of a principal to a key which
11  * is vouched for by another principal.  (A principal represents
12  * an entity such as an individual user, a group, or a corporation.)
13  *<p>
14  * This class is an abstraction for certificates that have different
15  * formats but important common uses.  For example, different types of
16  * certificates, such as X.509 and PGP, share general certificate
17  * functionality (like encoding and verifying) and
18  * some types of information (like a key).
19  * <p>
20  * X.509, PGP, and SDSI certificates can all be implemented by
21  * subclassing the Certificate class, even though they contain different
22  * sets of information, and they store and retrieve the information in
23  * different ways.
24  *
25  * @see X509Certificate
26  * @see CertificateFactory
27  *
28  * @author Hemma Prafullchandra
29  */
30 
31 abstract class Certificate {
32 
33     // private static final long serialVersionUID = -3585440601605666277L;
34 
35     // the certificate type
36     private string type;
37 
38     /** Cache the hash code for the certiticate */
39     private int hash = -1; // Default to -1
40 
41     /**
42      * Creates a certificate of the specified type.
43      *
44      * @param type the standard name of the certificate type.
45      * See the CertificateFactory section in the <a href=
46      * "{@docRoot}/../technotes/guides/security/StandardNames.html#CertificateFactory">
47      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
48      * for information about standard certificate types.
49      */
50     protected this(string type) {
51         this.type = type;
52     }
53 
54     /**
55      * Returns the type of this certificate.
56      *
57      * @return the type of this certificate.
58      */
59     final string getType() {
60         return this.type;
61     }
62 
63     /**
64      * Compares this certificate for equality with the specified
65      * object. If the {@code other} object is an
66      * {@code instanceof} {@code Certificate}, then
67      * its encoded form is retrieved and compared with the
68      * encoded form of this certificate.
69      *
70      * @param other the object to test for equality with this certificate.
71      * @return true iff the encoded forms of the two certificates
72      * match, false otherwise.
73      */
74     override bool opEquals(Object other) {
75         if (this is other) {
76             return true;
77         }
78         if (typeid(other) != typeid(Certificate)) {
79             return false;
80         }
81 
82         implementationMissing();
83         return false;
84         // try {
85         //     byte[] thisCert = X509CertImpl.getEncodedInternal(this);
86         //     byte[] otherCert = X509CertImpl.getEncodedInternal(cast(Certificate)other);
87 
88         //     return thisCert == otherCert;
89         // } catch (CertificateException e) {
90         //     return false;
91         // }
92     }
93 
94     /**
95      * Returns a hashcode value for this certificate from its
96      * encoded form.
97      *
98      * @return the hashcode value.
99      */
100     // int hashCode() {
101     //     int h = hash;
102     //     if (h == -1) {
103     //         try {
104     //             h = Arrays.hashCode(X509CertImpl.getEncodedInternal(this));
105     //         } catch (CertificateException e) {
106     //             h = 0;
107     //         }
108     //         hash = h;
109     //     }
110     //     return h;
111     // }
112 
113     /**
114      * Returns the encoded form of this certificate. It is
115      * assumed that each certificate type would have only a single
116      * form of encoding; for example, X.509 certificates would
117      * be encoded as ASN.1 DER.
118      *
119      * @return the encoded form of this certificate
120      *
121      * @exception CertificateEncodingException if an encoding error occurs.
122      */
123     abstract byte[] getEncoded();
124 
125     /**
126      * Verifies that this certificate was signed using the
127      * private key that corresponds to the specified key.
128      *
129      * @param key the PublicKey used to carry out the verification.
130      *
131      * @exception NoSuchAlgorithmException on unsupported signature
132      * algorithms.
133      * @exception InvalidKeyException on incorrect key.
134      * @exception NoSuchProviderException if there's no default provider.
135      * @exception SignatureException on signature errors.
136      * @exception CertificateException on encoding errors.
137      */
138     abstract void verify(PublicKey key);
139 
140     /**
141      * Verifies that this certificate was signed using the
142      * private key that corresponds to the specified key.
143      * This method uses the signature verification engine
144      * supplied by the specified provider.
145      *
146      * @param key the PublicKey used to carry out the verification.
147      * @param sigProvider the name of the signature provider.
148      *
149      * @exception NoSuchAlgorithmException on unsupported signature
150      * algorithms.
151      * @exception InvalidKeyException on incorrect key.
152      * @exception NoSuchProviderException on incorrect provider.
153      * @exception SignatureException on signature errors.
154      * @exception CertificateException on encoding errors.
155      */
156     abstract void verify(PublicKey key, string sigProvider);
157 
158     /**
159      * Verifies that this certificate was signed using the
160      * private key that corresponds to the specified key.
161      * This method uses the signature verification engine
162      * supplied by the specified provider. Note that the specified
163      * Provider object does not have to be registered in the provider list.
164      *
165      * <p> This method was added to version 1.8 of the Java Platform
166      * Standard Edition. In order to maintain backwards compatibility with
167      * existing service providers, this method cannot be {@code abstract}
168      * and by default throws an {@code UnsupportedOperationException}.
169      *
170      * @param key the PublicKey used to carry out the verification.
171      * @param sigProvider the signature provider.
172      *
173      * @exception NoSuchAlgorithmException on unsupported signature
174      * algorithms.
175      * @exception InvalidKeyException on incorrect key.
176      * @exception SignatureException on signature errors.
177      * @exception CertificateException on encoding errors.
178      * @exception UnsupportedOperationException if the method is not supported
179      * @since 1.8
180      */
181     void verify(PublicKey key, Provider sigProvider) {
182         throw new UnsupportedOperationException("");
183     }
184 
185     /**
186      * Returns a string representation of this certificate.
187      *
188      * @return a string representation of this certificate.
189      */
190     // abstract string toString();
191 
192     /**
193      * Gets the key from this certificate.
194      *
195      * @return the key.
196      */
197     abstract PublicKey getPublicKey();
198 
199     /**
200      * Alternate Certificate class for serialization.
201      * @since 1.3
202      */
203     protected static class CertificateRep  {
204 
205         // private static final long serialVersionUID = -8563758940495660020L;
206 
207         private string type;
208         private byte[] data;
209 
210         /**
211          * Construct the alternate Certificate class with the Certificate
212          * type and Certificate encoding bytes.
213          *
214          * <p>
215          *
216          * @param type the standard name of the Certificate type. <p>
217          *
218          * @param data the Certificate data.
219          */
220         protected this(string type, byte[] data) {
221             this.type = type;
222             this.data = data;
223         }
224 
225         /**
226          * Resolve the Certificate Object.
227          *
228          * <p>
229          *
230          * @return the resolved Certificate Object
231          *
232          * @throws java.io.ObjectStreamException if the Certificate
233          *      could not be resolved
234          */
235         // protected Object readResolve() {
236         //     try {
237         //         CertificateFactory cf = CertificateFactory.getInstance(type);
238         //         return cf.generateCertificate
239         //                 (new java.io.ByteArrayInputStream(data));
240         //     } catch (CertificateException e) {
241         //         throw new java.io.NotSerializableException
242         //                         ("java.security.cert.Certificate: " ~
243         //                         type +
244         //                         ": " ~
245         //                         e.getMessage());
246         //     }
247         // }
248     }
249 
250     /**
251      * Replace the Certificate to be serialized.
252      *
253      * @return the alternate Certificate object to be serialized
254      *
255      * @throws java.io.ObjectStreamException if a new object representing
256      * this Certificate could not be created
257      * @since 1.3
258      */
259     // protected Object writeReplace() {
260     //     try {
261     //         return new CertificateRep(type, getEncoded());
262     //     } catch (CertificateException e) {
263     //         throw new java.io.NotSerializableException
264     //                             ("java.security.cert.Certificate: " ~
265     //                             type ~
266     //                             ": " ~
267     //                             e.getMessage());
268     //     }
269     // }
270 }