x509.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  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. * @file x509.c
  32. *
  33. * Certificate processing.
  34. */
  35. #include <time.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include "os_port.h"
  40. #include "crypto_misc.h"
  41. #include "sockets.h"
  42. #include "config.h"
  43. #ifdef CONFIG_SSL_CERT_VERIFICATION
  44. /**
  45. * Retrieve the signature from a certificate.
  46. */
  47. static const uint8_t *get_signature(const uint8_t *asn1_sig, int *len)
  48. {
  49. int offset = 0;
  50. const uint8_t *ptr = NULL;
  51. if (asn1_next_obj(asn1_sig, &offset, ASN1_SEQUENCE) < 0 ||
  52. asn1_skip_obj(asn1_sig, &offset, ASN1_SEQUENCE))
  53. goto end_get_sig;
  54. if (asn1_sig[offset++] != ASN1_OCTET_STRING)
  55. goto end_get_sig;
  56. *len = get_asn1_length(asn1_sig, &offset);
  57. ptr = &asn1_sig[offset]; /* all ok */
  58. end_get_sig:
  59. return ptr;
  60. }
  61. #endif
  62. /**
  63. * Construct a new x509 object.
  64. * @return 0 if ok. < 0 if there was a problem.
  65. */
  66. int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
  67. {
  68. int begin_tbs, end_tbs;
  69. int ret = X509_NOT_OK, offset = 0, cert_size = 0;
  70. X509_CTX *x509_ctx;
  71. BI_CTX *bi_ctx;
  72. *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
  73. x509_ctx = *ctx;
  74. /* get the certificate size */
  75. asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE);
  76. if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
  77. goto end_cert;
  78. begin_tbs = offset; /* start of the tbs */
  79. end_tbs = begin_tbs; /* work out the end of the tbs */
  80. asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);
  81. if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
  82. goto end_cert;
  83. if (cert[offset] == ASN1_EXPLICIT_TAG) /* optional version */
  84. {
  85. if (asn1_version(cert, &offset, x509_ctx))
  86. goto end_cert;
  87. }
  88. if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */
  89. asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
  90. {
  91. goto end_cert;
  92. }
  93. /* make sure the signature is ok */
  94. if (asn1_signature_type(cert, &offset, x509_ctx))
  95. {
  96. ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
  97. goto end_cert;
  98. }
  99. if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) ||
  100. asn1_validity(cert, &offset, x509_ctx) ||
  101. asn1_name(cert, &offset, x509_ctx->cert_dn) ||
  102. asn1_public_key(cert, &offset, x509_ctx))
  103. {
  104. goto end_cert;
  105. }
  106. bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
  107. #ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
  108. /* use the appropriate signature algorithm (SHA1/MD5/MD2) */
  109. if (x509_ctx->sig_type == SIG_TYPE_MD5)
  110. {
  111. MD5_CTX md5_ctx;
  112. uint8_t md5_dgst[MD5_SIZE];
  113. MD5_Init(&md5_ctx);
  114. MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
  115. MD5_Final(md5_dgst, &md5_ctx);
  116. x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
  117. }
  118. else if (x509_ctx->sig_type == SIG_TYPE_SHA1)
  119. {
  120. SHA1_CTX sha_ctx;
  121. uint8_t sha_dgst[SHA1_SIZE];
  122. SHA1_Init(&sha_ctx);
  123. SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
  124. SHA1_Final(sha_dgst, &sha_ctx);
  125. x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
  126. }
  127. else if (x509_ctx->sig_type == SIG_TYPE_MD2)
  128. {
  129. MD2_CTX md2_ctx;
  130. uint8_t md2_dgst[MD2_SIZE];
  131. MD2_Init(&md2_ctx);
  132. MD2_Update(&md2_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
  133. MD2_Final(md2_dgst, &md2_ctx);
  134. x509_ctx->digest = bi_import(bi_ctx, md2_dgst, MD2_SIZE);
  135. }
  136. if (cert[offset] == ASN1_V3_DATA)
  137. {
  138. int suboffset;
  139. ++offset;
  140. get_asn1_length(cert, &offset);
  141. if ((suboffset = asn1_find_subjectaltname(cert, offset)) > 0)
  142. {
  143. if (asn1_next_obj(cert, &suboffset, ASN1_OCTET_STRING) > 0)
  144. {
  145. int altlen;
  146. if ((altlen = asn1_next_obj(cert,
  147. &suboffset, ASN1_SEQUENCE)) > 0)
  148. {
  149. int endalt = suboffset + altlen;
  150. int totalnames = 0;
  151. while (suboffset < endalt)
  152. {
  153. int type = cert[suboffset++];
  154. int dnslen = get_asn1_length(cert, &suboffset);
  155. if (type == ASN1_CONTEXT_DNSNAME)
  156. {
  157. x509_ctx->subject_alt_dnsnames = (char**)
  158. realloc(x509_ctx->subject_alt_dnsnames,
  159. (totalnames + 2) * sizeof(char*));
  160. x509_ctx->subject_alt_dnsnames[totalnames] =
  161. (char*)malloc(dnslen + 1);
  162. x509_ctx->subject_alt_dnsnames[totalnames+1] = NULL;
  163. memcpy(x509_ctx->subject_alt_dnsnames[totalnames],
  164. cert + suboffset, dnslen);
  165. x509_ctx->subject_alt_dnsnames[
  166. totalnames][dnslen] = 0;
  167. ++totalnames;
  168. }
  169. suboffset += dnslen;
  170. }
  171. }
  172. }
  173. }
  174. }
  175. offset = end_tbs; /* skip the rest of v3 data */
  176. if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) ||
  177. asn1_signature(cert, &offset, x509_ctx))
  178. goto end_cert;
  179. #endif
  180. ret = X509_OK;
  181. end_cert:
  182. if (len)
  183. {
  184. *len = cert_size;
  185. }
  186. if (ret)
  187. {
  188. #ifdef CONFIG_SSL_FULL_MODE
  189. printf("Error: Invalid X509 ASN.1 file (%s)\n",
  190. x509_display_error(ret));
  191. #endif
  192. x509_free(x509_ctx);
  193. *ctx = NULL;
  194. }
  195. return ret;
  196. }
  197. /**
  198. * Free an X.509 object's resources.
  199. */
  200. void x509_free(X509_CTX *x509_ctx)
  201. {
  202. X509_CTX *next;
  203. int i;
  204. if (x509_ctx == NULL) /* if already null, then don't bother */
  205. return;
  206. for (i = 0; i < X509_NUM_DN_TYPES; i++)
  207. {
  208. free(x509_ctx->ca_cert_dn[i]);
  209. free(x509_ctx->cert_dn[i]);
  210. }
  211. free(x509_ctx->signature);
  212. #ifdef CONFIG_SSL_CERT_VERIFICATION
  213. if (x509_ctx->digest)
  214. {
  215. bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest);
  216. }
  217. if (x509_ctx->subject_alt_dnsnames)
  218. {
  219. for (i = 0; x509_ctx->subject_alt_dnsnames[i]; ++i)
  220. free(x509_ctx->subject_alt_dnsnames[i]);
  221. free(x509_ctx->subject_alt_dnsnames);
  222. }
  223. #endif
  224. RSA_free(x509_ctx->rsa_ctx);
  225. next = x509_ctx->next;
  226. free(x509_ctx);
  227. x509_free(next); /* clear the chain */
  228. }
  229. #ifdef CONFIG_SSL_CERT_VERIFICATION
  230. /**
  231. * Take a signature and decrypt it.
  232. */
  233. static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
  234. bigint *modulus, bigint *pub_exp)
  235. {
  236. int i, size;
  237. bigint *decrypted_bi, *dat_bi;
  238. bigint *bir = NULL;
  239. uint8_t *block = (uint8_t *)alloca(sig_len);
  240. /* decrypt */
  241. dat_bi = bi_import(ctx, sig, sig_len);
  242. ctx->mod_offset = BIGINT_M_OFFSET;
  243. /* convert to a normal block */
  244. decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);
  245. bi_export(ctx, decrypted_bi, block, sig_len);
  246. ctx->mod_offset = BIGINT_M_OFFSET;
  247. i = 10; /* start at the first possible non-padded byte */
  248. while (block[i++] && i < sig_len);
  249. size = sig_len - i;
  250. /* get only the bit we want */
  251. if (size > 0)
  252. {
  253. int len;
  254. const uint8_t *sig_ptr = get_signature(&block[i], &len);
  255. if (sig_ptr)
  256. {
  257. bir = bi_import(ctx, sig_ptr, len);
  258. }
  259. }
  260. /* save a few bytes of memory */
  261. bi_clear_cache(ctx);
  262. return bir;
  263. }
  264. /**
  265. * Do some basic checks on the certificate chain.
  266. *
  267. * Certificate verification consists of a number of checks:
  268. * - The date of the certificate is after the start date.
  269. * - The date of the certificate is before the finish date.
  270. * - A root certificate exists in the certificate store.
  271. * - That the certificate(s) are not self-signed.
  272. * - The certificate chain is valid.
  273. * - The signature of the certificate is valid.
  274. */
  275. int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert)
  276. {
  277. int ret = X509_OK, i = 0;
  278. bigint *cert_sig;
  279. X509_CTX *next_cert = NULL;
  280. BI_CTX *ctx = NULL;
  281. bigint *mod = NULL, *expn = NULL;
  282. int match_ca_cert = 0;
  283. struct timeval tv;
  284. uint8_t is_self_signed = 0;
  285. if (cert == NULL)
  286. {
  287. ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
  288. goto end_verify;
  289. }
  290. /* a self-signed certificate that is not in the CA store - use this
  291. to check the signature */
  292. if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
  293. {
  294. printf("self signed cert\r\n");
  295. is_self_signed = 1;
  296. ctx = cert->rsa_ctx->bi_ctx;
  297. mod = cert->rsa_ctx->m;
  298. expn = cert->rsa_ctx->e;
  299. }
  300. gettimeofday(&tv, NULL);
  301. /* check the not before date */
  302. if (tv.tv_sec < cert->not_before)
  303. {
  304. ret = X509_VFY_ERROR_NOT_YET_VALID;
  305. goto end_verify;
  306. }
  307. /* check the not after date */
  308. if (tv.tv_sec > cert->not_after)
  309. {
  310. ret = X509_VFY_ERROR_EXPIRED;
  311. goto end_verify;
  312. }
  313. next_cert = cert->next;
  314. /* last cert in the chain - look for a trusted cert */
  315. if (next_cert == NULL)
  316. {
  317. if (ca_cert_ctx != NULL)
  318. {
  319. /* go thu the CA store */
  320. while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
  321. {
  322. if (asn1_compare_dn(cert->ca_cert_dn,
  323. ca_cert_ctx->cert[i]->cert_dn) == 0)
  324. {
  325. /* use this CA certificate for signature verification */
  326. match_ca_cert = 1;
  327. ctx = ca_cert_ctx->cert[i]->rsa_ctx->bi_ctx;
  328. mod = ca_cert_ctx->cert[i]->rsa_ctx->m;
  329. expn = ca_cert_ctx->cert[i]->rsa_ctx->e;
  330. break;
  331. }
  332. i++;
  333. }
  334. }
  335. /* couldn't find a trusted cert (& let self-signed errors
  336. be returned) */
  337. if (!match_ca_cert && !is_self_signed)
  338. {
  339. ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
  340. goto end_verify;
  341. }
  342. }
  343. else if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0)
  344. {
  345. /* check the chain */
  346. ret = X509_VFY_ERROR_INVALID_CHAIN;
  347. goto end_verify;
  348. }
  349. else /* use the next certificate in the chain for signature verify */
  350. {
  351. ctx = next_cert->rsa_ctx->bi_ctx;
  352. mod = next_cert->rsa_ctx->m;
  353. expn = next_cert->rsa_ctx->e;
  354. }
  355. /* cert is self signed */
  356. if (!match_ca_cert && is_self_signed)
  357. {
  358. ret = X509_VFY_ERROR_SELF_SIGNED;
  359. goto end_verify;
  360. }
  361. /* check the signature */
  362. cert_sig = sig_verify(ctx, cert->signature, cert->sig_len,
  363. bi_clone(ctx, mod), bi_clone(ctx, expn));
  364. if (cert_sig && cert->digest)
  365. {
  366. if (bi_compare(cert_sig, cert->digest) != 0)
  367. ret = X509_VFY_ERROR_BAD_SIGNATURE;
  368. bi_free(ctx, cert_sig);
  369. }
  370. else
  371. {
  372. ret = X509_VFY_ERROR_BAD_SIGNATURE;
  373. }
  374. if (ret)
  375. goto end_verify;
  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. end_verify:
  382. return ret;
  383. }
  384. #endif
  385. #if defined (CONFIG_SSL_FULL_MODE)
  386. /**
  387. * Used for diagnostics.
  388. */
  389. static const char *not_part_of_cert = "<Not Part Of Certificate>";
  390. void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx)
  391. {
  392. if (cert == NULL)
  393. return;
  394. printf("=== CERTIFICATE ISSUED TO ===\n");
  395. printf("Common Name (CN):\t\t");
  396. printf("%s\r\n", cert->cert_dn[X509_COMMON_NAME] ?
  397. cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert);
  398. printf("Organization (O):\t\t");
  399. printf("%s\r\n", cert->cert_dn[X509_ORGANIZATION] ?
  400. cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert);
  401. printf("Organizational Unit (OU):\t");
  402. printf("%s\r\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT] ?
  403. cert->cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
  404. printf("=== CERTIFICATE ISSUED BY ===\r\n");
  405. printf("Common Name (CN):\t\t");
  406. printf("%s\r\n", cert->ca_cert_dn[X509_COMMON_NAME] ?
  407. cert->ca_cert_dn[X509_COMMON_NAME] : not_part_of_cert);
  408. printf("Organization (O):\t\t");
  409. printf("%s\r\n", cert->ca_cert_dn[X509_ORGANIZATION] ?
  410. cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert);
  411. printf("Organizational Unit (OU):\t");
  412. printf("%s\r\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] ?
  413. cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);
  414. printf("Not Before:\t\t\t%s\r\n", ctime(&cert->not_before));
  415. printf("Not After:\t\t\t%s\r\n", ctime(&cert->not_after));
  416. printf("RSA bitsize:\t\t\t%d\r\n", cert->rsa_ctx->num_octets*8);
  417. printf("Sig Type:\t\t\t");
  418. switch (cert->sig_type)
  419. {
  420. case SIG_TYPE_MD5:
  421. printf("MD5\r\n");
  422. break;
  423. case SIG_TYPE_SHA1:
  424. printf("SHA1\r\n");
  425. break;
  426. case SIG_TYPE_MD2:
  427. printf("MD2\r\n");
  428. break;
  429. default:
  430. printf("Unrecognized: %d\r\n", cert->sig_type);
  431. break;
  432. }
  433. if (ca_cert_ctx)
  434. {
  435. printf("Verify:\t\t\t\t%s\r\n",
  436. x509_display_error(x509_verify(ca_cert_ctx, cert)));
  437. }
  438. #if 0
  439. print_blob("Signature", cert->signature, cert->sig_len);
  440. bi_print("Modulus", cert->rsa_ctx->m);
  441. bi_print("Pub Exp", cert->rsa_ctx->e);
  442. #endif
  443. if (ca_cert_ctx)
  444. {
  445. x509_print(cert->next, ca_cert_ctx);
  446. }
  447. TTY_FLUSH();
  448. }
  449. const char * x509_display_error(int error)
  450. {
  451. switch (error)
  452. {
  453. case X509_OK:
  454. return "Certificate verify successful";
  455. case X509_NOT_OK:
  456. return "X509 not ok";
  457. case X509_VFY_ERROR_NO_TRUSTED_CERT:
  458. return "No trusted cert is available";
  459. case X509_VFY_ERROR_BAD_SIGNATURE:
  460. return "Bad signature";
  461. case X509_VFY_ERROR_NOT_YET_VALID:
  462. return "Cert is not yet valid";
  463. case X509_VFY_ERROR_EXPIRED:
  464. return "Cert has expired";
  465. case X509_VFY_ERROR_SELF_SIGNED:
  466. return "Cert is self-signed";
  467. case X509_VFY_ERROR_INVALID_CHAIN:
  468. return "Chain is invalid (check order of certs)";
  469. case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
  470. return "Unsupported digest";
  471. case X509_INVALID_PRIV_KEY:
  472. return "Invalid private key";
  473. default:
  474. return "Unknown";
  475. }
  476. }
  477. #endif /* CONFIG_SSL_FULL_MODE */