Merge pull request #1818 from dibdot/lxc_fix
[project/luci.git] / libs / luci-lib-nixio / axTLS / ssl / x509.c
1 /*
2  * Copyright (c) 2007, Cameron Rich
3  * 
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright notice, 
10  *   this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright notice, 
12  *   this list of conditions and the following disclaimer in the documentation 
13  *   and/or other materials provided with the distribution.
14  * * Neither the name of the axTLS project nor the names of its contributors 
15  *   may be used to endorse or promote products derived from this software 
16  *   without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 /**
32  * @file x509.c
33  * 
34  * Certificate processing.
35  */
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <time.h>
41 #include "os_port.h"
42 #include "crypto_misc.h"
43
44 #ifdef CONFIG_SSL_CERT_VERIFICATION
45 /**
46  * Retrieve the signature from a certificate.
47  */
48 static const uint8_t *get_signature(const uint8_t *asn1_sig, int *len)
49 {
50     int offset = 0;
51     const uint8_t *ptr = NULL;
52
53     if (asn1_next_obj(asn1_sig, &offset, ASN1_SEQUENCE) < 0 || 
54             asn1_skip_obj(asn1_sig, &offset, ASN1_SEQUENCE))
55         goto end_get_sig;
56
57     if (asn1_sig[offset++] != ASN1_OCTET_STRING)
58         goto end_get_sig;
59     *len = get_asn1_length(asn1_sig, &offset);
60     ptr = &asn1_sig[offset];          /* all ok */
61
62 end_get_sig:
63     return ptr;
64 }
65
66 #endif
67
68 /**
69  * Construct a new x509 object.
70  * @return 0 if ok. < 0 if there was a problem.
71  */
72 int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
73 {
74     int begin_tbs, end_tbs;
75     int ret = X509_NOT_OK, offset = 0, cert_size = 0;
76     X509_CTX *x509_ctx;
77     BI_CTX *bi_ctx;
78
79     *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
80     x509_ctx = *ctx;
81
82     /* get the certificate size */
83     asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE); 
84
85     if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
86         goto end_cert;
87
88     begin_tbs = offset;         /* start of the tbs */
89     end_tbs = begin_tbs;        /* work out the end of the tbs */
90     asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);
91
92     if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
93         goto end_cert;
94
95     if (cert[offset] == ASN1_EXPLICIT_TAG)   /* optional version */
96     {
97         if (asn1_version(cert, &offset, x509_ctx))
98             goto end_cert;
99     }
100
101     if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */ 
102             asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
103         goto end_cert;
104
105     /* make sure the signature is ok */
106     if (asn1_signature_type(cert, &offset, x509_ctx))
107     {
108         ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
109         goto end_cert;
110     }
111
112     if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) || 
113             asn1_validity(cert, &offset, x509_ctx) ||
114             asn1_name(cert, &offset, x509_ctx->cert_dn) ||
115             asn1_public_key(cert, &offset, x509_ctx))
116         goto end_cert;
117
118     bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
119
120 #ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
121     /* use the appropriate signature algorithm (SHA1/MD5/MD2) */
122     if (x509_ctx->sig_type == SIG_TYPE_MD5)
123     {
124         MD5_CTX md5_ctx;
125         uint8_t md5_dgst[MD5_SIZE];
126         MD5_Init(&md5_ctx);
127         MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
128         MD5_Final(md5_dgst, &md5_ctx);
129         x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
130     }
131     else if (x509_ctx->sig_type == SIG_TYPE_SHA1)
132     {
133         SHA1_CTX sha_ctx;
134         uint8_t sha_dgst[SHA1_SIZE];
135         SHA1_Init(&sha_ctx);
136         SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
137         SHA1_Final(sha_dgst, &sha_ctx);
138         x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
139     }
140     else if (x509_ctx->sig_type == SIG_TYPE_MD2)
141     {
142         MD2_CTX md2_ctx;
143         uint8_t md2_dgst[MD2_SIZE];
144         MD2_Init(&md2_ctx);
145         MD2_Update(&md2_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
146         MD2_Final(md2_dgst, &md2_ctx);
147         x509_ctx->digest = bi_import(bi_ctx, md2_dgst, MD2_SIZE);
148     }
149
150     offset = end_tbs;   /* skip the v3 data */
151     if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) || 
152             asn1_signature(cert, &offset, x509_ctx))
153         goto end_cert;
154 #endif
155
156     if (len)
157     {
158         *len = cert_size;
159     }
160
161     ret = X509_OK;
162 end_cert:
163
164 #ifdef CONFIG_SSL_FULL_MODE
165     if (ret)
166     {
167         printf("Error: Invalid X509 ASN.1 file\n");
168     }
169 #endif
170
171     return ret;
172 }
173
174 /**
175  * Free an X.509 object's resources.
176  */
177 void x509_free(X509_CTX *x509_ctx)
178 {
179     X509_CTX *next;
180     int i;
181
182     if (x509_ctx == NULL)       /* if already null, then don't bother */
183         return;
184
185     for (i = 0; i < X509_NUM_DN_TYPES; i++)
186     {
187         free(x509_ctx->ca_cert_dn[i]);
188         free(x509_ctx->cert_dn[i]);
189     }
190
191     free(x509_ctx->signature);
192
193 #ifdef CONFIG_SSL_CERT_VERIFICATION 
194     if (x509_ctx->digest)
195     {
196         bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest);
197     }
198 #endif
199
200     RSA_free(x509_ctx->rsa_ctx);
201
202     next = x509_ctx->next;
203     free(x509_ctx);
204     x509_free(next);        /* clear the chain */
205 }
206
207 #ifdef CONFIG_SSL_CERT_VERIFICATION
208 /**
209  * Take a signature and decrypt it.
210  */
211 static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
212         bigint *modulus, bigint *pub_exp)
213 {
214     int i, size;
215     bigint *decrypted_bi, *dat_bi;
216     bigint *bir = NULL;
217     uint8_t *block = (uint8_t *)alloca(sig_len);
218
219     /* decrypt */
220     dat_bi = bi_import(ctx, sig, sig_len);
221     ctx->mod_offset = BIGINT_M_OFFSET;
222
223     /* convert to a normal block */
224     decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);
225
226     bi_export(ctx, decrypted_bi, block, sig_len);
227     ctx->mod_offset = BIGINT_M_OFFSET;
228
229     i = 10; /* start at the first possible non-padded byte */
230     while (block[i++] && i < sig_len);
231     size = sig_len - i;
232
233     /* get only the bit we want */
234     if (size > 0)
235     {
236         int len;
237         const uint8_t *sig_ptr = get_signature(&block[i], &len);
238
239         if (sig_ptr)
240         {
241             bir = bi_import(ctx, sig_ptr, len);
242         }
243     }
244
245     /* save a few bytes of memory */
246     bi_clear_cache(ctx);
247     return bir;
248 }
249
250 /**
251  * Do some basic checks on the certificate chain.
252  *
253  * Certificate verification consists of a number of checks:
254  * - The date of the certificate is after the start date.
255  * - The date of the certificate is before the finish date.
256  * - A root certificate exists in the certificate store.
257  * - That the certificate(s) are not self-signed.
258  * - The certificate chain is valid.
259  * - The signature of the certificate is valid.
260  */
261 int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert) 
262 {
263     int ret = X509_OK, i = 0;
264     bigint *cert_sig;
265     X509_CTX *next_cert = NULL;
266     BI_CTX *ctx = NULL;
267     bigint *mod = NULL, *expn = NULL;
268     int match_ca_cert = 0;
269     struct timeval tv;
270     uint8_t is_self_signed = 0;
271
272     if (cert == NULL)
273     {
274         ret = X509_VFY_ERROR_NO_TRUSTED_CERT;       
275         goto end_verify;
276     }
277
278     /* a self-signed certificate that is not in the CA store - use this 
279        to check the signature */
280     if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
281     {
282         is_self_signed = 1;
283         ctx = cert->rsa_ctx->bi_ctx;
284         mod = cert->rsa_ctx->m;
285         expn = cert->rsa_ctx->e;
286     }
287
288     gettimeofday(&tv, NULL);
289
290     /* check the not before date */
291     if (tv.tv_sec < cert->not_before)
292     {
293         ret = X509_VFY_ERROR_NOT_YET_VALID;
294         goto end_verify;
295     }
296
297     /* check the not after date */
298     if (tv.tv_sec > cert->not_after)
299     {
300         ret = X509_VFY_ERROR_EXPIRED;
301         goto end_verify;
302     }
303
304     next_cert = cert->next;
305
306     /* last cert in the chain - look for a trusted cert */
307     if (next_cert == NULL)
308     {
309        if (ca_cert_ctx != NULL) 
310        {
311             /* go thu the CA store */
312            while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
313             {
314                 if (asn1_compare_dn(cert->ca_cert_dn,
315                                             ca_cert_ctx->cert[i]->cert_dn) == 0)
316                 {
317                     /* use this CA certificate for signature verification */
318                     match_ca_cert = 1;
319                     ctx = ca_cert_ctx->cert[i]->rsa_ctx->bi_ctx;
320                     mod = ca_cert_ctx->cert[i]->rsa_ctx->m;
321                     expn = ca_cert_ctx->cert[i]->rsa_ctx->e;
322                     break;
323                 }
324
325                 i++;
326             }
327         }
328
329        /* couldn't find a trusted cert (& let self-signed errors be returned) */
330         if (!match_ca_cert && !is_self_signed)
331         {
332             ret = X509_VFY_ERROR_NO_TRUSTED_CERT;       
333             goto end_verify;
334         }
335     }
336     else if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0)
337     {
338         /* check the chain */
339         ret = X509_VFY_ERROR_INVALID_CHAIN;
340         goto end_verify;
341     }
342     else /* use the next certificate in the chain for signature verify */
343     {
344         ctx = next_cert->rsa_ctx->bi_ctx;
345         mod = next_cert->rsa_ctx->m;
346         expn = next_cert->rsa_ctx->e;
347     }
348
349     /* cert is self signed */
350     if (!match_ca_cert && is_self_signed)
351     {
352         ret = X509_VFY_ERROR_SELF_SIGNED;
353         goto end_verify;
354     }
355
356     /* check the signature */
357     cert_sig = sig_verify(ctx, cert->signature, cert->sig_len, 
358                         bi_clone(ctx, mod), bi_clone(ctx, expn));
359
360     if (cert_sig && cert->digest)
361     {
362         if (bi_compare(cert_sig, cert->digest) != 0)
363             ret = X509_VFY_ERROR_BAD_SIGNATURE;
364
365
366         bi_free(ctx, cert_sig);
367     }
368     else
369     {
370         ret = X509_VFY_ERROR_BAD_SIGNATURE;
371     }
372
373     if (ret)
374         goto end_verify;
375
376     /* go down the certificate chain using recursion. */
377     if (next_cert != NULL)
378     {
379         ret = x509_verify(ca_cert_ctx, next_cert);
380     }
381
382 end_verify:
383     return ret;
384 }
385 #endif
386
387 #if defined (CONFIG_SSL_FULL_MODE)
388 /**
389  * Used for diagnostics.
390  */
391 static const char *not_part_of_cert = "<Not Part Of Certificate>";
392 void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx) 
393 {
394     if (cert == NULL)
395         return;
396
397     printf("=== CERTIFICATE ISSUED TO ===\n");
398     printf("Common Name (CN):\t\t");
399     printf("%s\n", cert->cert_dn[X509_COMMON_NAME] ?
400                     cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert);
401
402     printf("Organization (O):\t\t");
403     printf("%s\n", cert->cert_dn[X509_ORGANIZATION] ?
404         cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert);
405
406     printf("Organizational Unit (OU):\t");
407     printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT] ?
408         cert->cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
409
410     printf("=== CERTIFICATE ISSUED BY ===\n");
411     printf("Common Name (CN):\t\t");
412     printf("%s\n", cert->ca_cert_dn[X509_COMMON_NAME] ?
413                     cert->ca_cert_dn[X509_COMMON_NAME] : not_part_of_cert);
414
415     printf("Organization (O):\t\t");
416     printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATION] ?
417         cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert);
418
419     printf("Organizational Unit (OU):\t");
420     printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] ?
421         cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
422
423     printf("Not Before:\t\t\t%s", ctime(&cert->not_before));
424     printf("Not After:\t\t\t%s", ctime(&cert->not_after));
425     printf("RSA bitsize:\t\t\t%d\n", cert->rsa_ctx->num_octets*8);
426     printf("Sig Type:\t\t\t");
427     switch (cert->sig_type)
428     {
429         case SIG_TYPE_MD5:
430             printf("MD5\n");
431             break;
432         case SIG_TYPE_SHA1:
433             printf("SHA1\n");
434             break;
435         case SIG_TYPE_MD2:
436             printf("MD2\n");
437             break;
438         default:
439             printf("Unrecognized: %d\n", cert->sig_type);
440             break;
441     }
442
443     if (ca_cert_ctx)
444     {
445         printf("Verify:\t\t\t\t%s\n",
446                 x509_display_error(x509_verify(ca_cert_ctx, cert)));
447     }
448
449 #if 0
450     print_blob("Signature", cert->signature, cert->sig_len);
451     bi_print("Modulus", cert->rsa_ctx->m);
452     bi_print("Pub Exp", cert->rsa_ctx->e);
453 #endif
454
455     if (ca_cert_ctx)
456     {
457         x509_print(cert->next, ca_cert_ctx);
458     }
459
460     TTY_FLUSH();
461 }
462
463 const char * x509_display_error(int error)
464 {
465     switch (error)
466     {
467         case X509_OK:
468             return "Certificate verify successful";
469
470         case X509_NOT_OK:
471             return "X509 not ok";
472
473         case X509_VFY_ERROR_NO_TRUSTED_CERT:
474             return "No trusted cert is available";
475
476         case X509_VFY_ERROR_BAD_SIGNATURE:
477             return "Bad signature";
478
479         case X509_VFY_ERROR_NOT_YET_VALID:
480             return "Cert is not yet valid";
481
482         case X509_VFY_ERROR_EXPIRED:
483             return "Cert has expired";
484
485         case X509_VFY_ERROR_SELF_SIGNED:
486             return "Cert is self-signed";
487
488         case X509_VFY_ERROR_INVALID_CHAIN:
489             return "Chain is invalid (check order of certs)";
490
491         case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
492             return "Unsupported digest";
493
494         case X509_INVALID_PRIV_KEY:
495             return "Invalid private key";
496
497         default:
498             return "Unknown";
499     }
500 }
501 #endif      /* CONFIG_SSL_FULL_MODE */
502