1
0

x509.c 14 KB

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