x509_cert_parser.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. /* X.509 certificate parser
  2. *
  3. * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public Licence
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the Licence, or (at your option) any later version.
  10. */
  11. #define pr_fmt(fmt) "X.509: "fmt
  12. #include <linux/kernel.h>
  13. #include <linux/slab.h>
  14. #include <linux/err.h>
  15. #include <linux/oid_registry.h>
  16. #include "public_key.h"
  17. #include "x509_parser.h"
  18. #include "x509-asn1.h"
  19. #include "x509_rsakey-asn1.h"
  20. struct x509_parse_context {
  21. struct x509_certificate *cert; /* Certificate being constructed */
  22. unsigned long data; /* Start of data */
  23. const void *cert_start; /* Start of cert content */
  24. const void *key; /* Key data */
  25. size_t key_size; /* Size of key data */
  26. enum OID last_oid; /* Last OID encountered */
  27. enum OID algo_oid; /* Algorithm OID */
  28. unsigned char nr_mpi; /* Number of MPIs stored */
  29. u8 o_size; /* Size of organizationName (O) */
  30. u8 cn_size; /* Size of commonName (CN) */
  31. u8 email_size; /* Size of emailAddress */
  32. u16 o_offset; /* Offset of organizationName (O) */
  33. u16 cn_offset; /* Offset of commonName (CN) */
  34. u16 email_offset; /* Offset of emailAddress */
  35. };
  36. /*
  37. * Free an X.509 certificate
  38. */
  39. void x509_free_certificate(struct x509_certificate *cert)
  40. {
  41. if (cert) {
  42. public_key_destroy(cert->pub);
  43. kfree(cert->issuer);
  44. kfree(cert->subject);
  45. kfree(cert->fingerprint);
  46. kfree(cert->authority);
  47. kfree(cert);
  48. }
  49. }
  50. /*
  51. * Parse an X.509 certificate
  52. */
  53. struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
  54. {
  55. struct x509_certificate *cert;
  56. struct x509_parse_context *ctx;
  57. long ret;
  58. ret = -ENOMEM;
  59. cert = kzalloc(sizeof(struct x509_certificate), GFP_KERNEL);
  60. if (!cert)
  61. goto error_no_cert;
  62. cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
  63. if (!cert->pub)
  64. goto error_no_ctx;
  65. ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
  66. if (!ctx)
  67. goto error_no_ctx;
  68. ctx->cert = cert;
  69. ctx->data = (unsigned long)data;
  70. /* Attempt to decode the certificate */
  71. ret = asn1_ber_decoder(&x509_decoder, ctx, data, datalen);
  72. if (ret < 0)
  73. goto error_decode;
  74. /* Decode the public key */
  75. ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx,
  76. ctx->key, ctx->key_size);
  77. if (ret < 0)
  78. goto error_decode;
  79. kfree(ctx);
  80. return cert;
  81. error_decode:
  82. kfree(ctx);
  83. error_no_ctx:
  84. x509_free_certificate(cert);
  85. error_no_cert:
  86. return ERR_PTR(ret);
  87. }
  88. /*
  89. * Note an OID when we find one for later processing when we know how
  90. * to interpret it.
  91. */
  92. int x509_note_OID(void *context, size_t hdrlen,
  93. unsigned char tag,
  94. const void *value, size_t vlen)
  95. {
  96. struct x509_parse_context *ctx = context;
  97. ctx->last_oid = look_up_OID(value, vlen);
  98. if (ctx->last_oid == OID__NR) {
  99. char buffer[50];
  100. sprint_oid(value, vlen, buffer, sizeof(buffer));
  101. pr_debug("Unknown OID: [%lu] %s\n",
  102. (unsigned long)value - ctx->data, buffer);
  103. }
  104. return 0;
  105. }
  106. /*
  107. * Save the position of the TBS data so that we can check the signature over it
  108. * later.
  109. */
  110. int x509_note_tbs_certificate(void *context, size_t hdrlen,
  111. unsigned char tag,
  112. const void *value, size_t vlen)
  113. {
  114. struct x509_parse_context *ctx = context;
  115. pr_debug("x509_note_tbs_certificate(,%zu,%02x,%ld,%zu)!\n",
  116. hdrlen, tag, (unsigned long)value - ctx->data, vlen);
  117. ctx->cert->tbs = value - hdrlen;
  118. ctx->cert->tbs_size = vlen + hdrlen;
  119. return 0;
  120. }
  121. /*
  122. * Record the public key algorithm
  123. */
  124. int x509_note_pkey_algo(void *context, size_t hdrlen,
  125. unsigned char tag,
  126. const void *value, size_t vlen)
  127. {
  128. struct x509_parse_context *ctx = context;
  129. pr_debug("PubKey Algo: %u\n", ctx->last_oid);
  130. switch (ctx->last_oid) {
  131. case OID_md2WithRSAEncryption:
  132. case OID_md3WithRSAEncryption:
  133. default:
  134. return -ENOPKG; /* Unsupported combination */
  135. case OID_md4WithRSAEncryption:
  136. ctx->cert->sig_hash_algo = PKEY_HASH_MD5;
  137. ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
  138. break;
  139. case OID_sha1WithRSAEncryption:
  140. ctx->cert->sig_hash_algo = PKEY_HASH_SHA1;
  141. ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
  142. break;
  143. case OID_sha256WithRSAEncryption:
  144. ctx->cert->sig_hash_algo = PKEY_HASH_SHA256;
  145. ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
  146. break;
  147. case OID_sha384WithRSAEncryption:
  148. ctx->cert->sig_hash_algo = PKEY_HASH_SHA384;
  149. ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
  150. break;
  151. case OID_sha512WithRSAEncryption:
  152. ctx->cert->sig_hash_algo = PKEY_HASH_SHA512;
  153. ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
  154. break;
  155. case OID_sha224WithRSAEncryption:
  156. ctx->cert->sig_hash_algo = PKEY_HASH_SHA224;
  157. ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
  158. break;
  159. }
  160. ctx->algo_oid = ctx->last_oid;
  161. return 0;
  162. }
  163. /*
  164. * Note the whereabouts and type of the signature.
  165. */
  166. int x509_note_signature(void *context, size_t hdrlen,
  167. unsigned char tag,
  168. const void *value, size_t vlen)
  169. {
  170. struct x509_parse_context *ctx = context;
  171. pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen);
  172. if (ctx->last_oid != ctx->algo_oid) {
  173. pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n",
  174. ctx->algo_oid, ctx->last_oid);
  175. return -EINVAL;
  176. }
  177. ctx->cert->sig = value;
  178. ctx->cert->sig_size = vlen;
  179. return 0;
  180. }
  181. /*
  182. * Note some of the name segments from which we'll fabricate a name.
  183. */
  184. int x509_extract_name_segment(void *context, size_t hdrlen,
  185. unsigned char tag,
  186. const void *value, size_t vlen)
  187. {
  188. struct x509_parse_context *ctx = context;
  189. switch (ctx->last_oid) {
  190. case OID_commonName:
  191. ctx->cn_size = vlen;
  192. ctx->cn_offset = (unsigned long)value - ctx->data;
  193. break;
  194. case OID_organizationName:
  195. ctx->o_size = vlen;
  196. ctx->o_offset = (unsigned long)value - ctx->data;
  197. break;
  198. case OID_email_address:
  199. ctx->email_size = vlen;
  200. ctx->email_offset = (unsigned long)value - ctx->data;
  201. break;
  202. default:
  203. break;
  204. }
  205. return 0;
  206. }
  207. /*
  208. * Fabricate and save the issuer and subject names
  209. */
  210. static int x509_fabricate_name(struct x509_parse_context *ctx, size_t hdrlen,
  211. unsigned char tag,
  212. char **_name, size_t vlen)
  213. {
  214. const void *name, *data = (const void *)ctx->data;
  215. size_t namesize;
  216. char *buffer;
  217. if (*_name)
  218. return -EINVAL;
  219. /* Empty name string if no material */
  220. if (!ctx->cn_size && !ctx->o_size && !ctx->email_size) {
  221. buffer = kmalloc(1, GFP_KERNEL);
  222. if (!buffer)
  223. return -ENOMEM;
  224. buffer[0] = 0;
  225. goto done;
  226. }
  227. if (ctx->cn_size && ctx->o_size) {
  228. /* Consider combining O and CN, but use only the CN if it is
  229. * prefixed by the O, or a significant portion thereof.
  230. */
  231. namesize = ctx->cn_size;
  232. name = data + ctx->cn_offset;
  233. if (ctx->cn_size >= ctx->o_size &&
  234. memcmp(data + ctx->cn_offset, data + ctx->o_offset,
  235. ctx->o_size) == 0)
  236. goto single_component;
  237. if (ctx->cn_size >= 7 &&
  238. ctx->o_size >= 7 &&
  239. memcmp(data + ctx->cn_offset, data + ctx->o_offset, 7) == 0)
  240. goto single_component;
  241. buffer = kmalloc(ctx->o_size + 2 + ctx->cn_size + 1,
  242. GFP_KERNEL);
  243. if (!buffer)
  244. return -ENOMEM;
  245. memcpy(buffer,
  246. data + ctx->o_offset, ctx->o_size);
  247. buffer[ctx->o_size + 0] = ':';
  248. buffer[ctx->o_size + 1] = ' ';
  249. memcpy(buffer + ctx->o_size + 2,
  250. data + ctx->cn_offset, ctx->cn_size);
  251. buffer[ctx->o_size + 2 + ctx->cn_size] = 0;
  252. goto done;
  253. } else if (ctx->cn_size) {
  254. namesize = ctx->cn_size;
  255. name = data + ctx->cn_offset;
  256. } else if (ctx->o_size) {
  257. namesize = ctx->o_size;
  258. name = data + ctx->o_offset;
  259. } else {
  260. namesize = ctx->email_size;
  261. name = data + ctx->email_offset;
  262. }
  263. single_component:
  264. buffer = kmalloc(namesize + 1, GFP_KERNEL);
  265. if (!buffer)
  266. return -ENOMEM;
  267. memcpy(buffer, name, namesize);
  268. buffer[namesize] = 0;
  269. done:
  270. *_name = buffer;
  271. ctx->cn_size = 0;
  272. ctx->o_size = 0;
  273. ctx->email_size = 0;
  274. return 0;
  275. }
  276. int x509_note_issuer(void *context, size_t hdrlen,
  277. unsigned char tag,
  278. const void *value, size_t vlen)
  279. {
  280. struct x509_parse_context *ctx = context;
  281. return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen);
  282. }
  283. int x509_note_subject(void *context, size_t hdrlen,
  284. unsigned char tag,
  285. const void *value, size_t vlen)
  286. {
  287. struct x509_parse_context *ctx = context;
  288. return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->subject, vlen);
  289. }
  290. /*
  291. * Extract the data for the public key algorithm
  292. */
  293. int x509_extract_key_data(void *context, size_t hdrlen,
  294. unsigned char tag,
  295. const void *value, size_t vlen)
  296. {
  297. struct x509_parse_context *ctx = context;
  298. if (ctx->last_oid != OID_rsaEncryption)
  299. return -ENOPKG;
  300. /* There seems to be an extraneous 0 byte on the front of the data */
  301. ctx->cert->pkey_algo = PKEY_ALGO_RSA;
  302. ctx->key = value + 1;
  303. ctx->key_size = vlen - 1;
  304. return 0;
  305. }
  306. /*
  307. * Extract a RSA public key value
  308. */
  309. int rsa_extract_mpi(void *context, size_t hdrlen,
  310. unsigned char tag,
  311. const void *value, size_t vlen)
  312. {
  313. struct x509_parse_context *ctx = context;
  314. MPI mpi;
  315. if (ctx->nr_mpi >= ARRAY_SIZE(ctx->cert->pub->mpi)) {
  316. pr_err("Too many public key MPIs in certificate\n");
  317. return -EBADMSG;
  318. }
  319. mpi = mpi_read_raw_data(value, vlen);
  320. if (!mpi)
  321. return -ENOMEM;
  322. ctx->cert->pub->mpi[ctx->nr_mpi++] = mpi;
  323. return 0;
  324. }
  325. /*
  326. * Process certificate extensions that are used to qualify the certificate.
  327. */
  328. int x509_process_extension(void *context, size_t hdrlen,
  329. unsigned char tag,
  330. const void *value, size_t vlen)
  331. {
  332. struct x509_parse_context *ctx = context;
  333. const unsigned char *v = value;
  334. char *f;
  335. int i;
  336. pr_debug("Extension: %u\n", ctx->last_oid);
  337. if (ctx->last_oid == OID_subjectKeyIdentifier) {
  338. /* Get hold of the key fingerprint */
  339. if (vlen < 3)
  340. return -EBADMSG;
  341. if (v[0] != ASN1_OTS || v[1] != vlen - 2)
  342. return -EBADMSG;
  343. v += 2;
  344. vlen -= 2;
  345. f = kmalloc(vlen * 2 + 1, GFP_KERNEL);
  346. if (!f)
  347. return -ENOMEM;
  348. for (i = 0; i < vlen; i++)
  349. sprintf(f + i * 2, "%02x", v[i]);
  350. pr_debug("fingerprint %s\n", f);
  351. ctx->cert->fingerprint = f;
  352. return 0;
  353. }
  354. if (ctx->last_oid == OID_authorityKeyIdentifier) {
  355. /* Get hold of the CA key fingerprint */
  356. if (vlen < 5)
  357. return -EBADMSG;
  358. if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)) ||
  359. v[1] != vlen - 2 ||
  360. v[2] != (ASN1_CONT << 6) ||
  361. v[3] != vlen - 4)
  362. return -EBADMSG;
  363. v += 4;
  364. vlen -= 4;
  365. f = kmalloc(vlen * 2 + 1, GFP_KERNEL);
  366. if (!f)
  367. return -ENOMEM;
  368. for (i = 0; i < vlen; i++)
  369. sprintf(f + i * 2, "%02x", v[i]);
  370. pr_debug("authority %s\n", f);
  371. ctx->cert->authority = f;
  372. return 0;
  373. }
  374. return 0;
  375. }
  376. /*
  377. * Record a certificate time.
  378. */
  379. static int x509_note_time(struct tm *tm, size_t hdrlen,
  380. unsigned char tag,
  381. const unsigned char *value, size_t vlen)
  382. {
  383. const unsigned char *p = value;
  384. #define dec2bin(X) ((X) - '0')
  385. #define DD2bin(P) ({ unsigned x = dec2bin(P[0]) * 10 + dec2bin(P[1]); P += 2; x; })
  386. if (tag == ASN1_UNITIM) {
  387. /* UTCTime: YYMMDDHHMMSSZ */
  388. if (vlen != 13)
  389. goto unsupported_time;
  390. tm->tm_year = DD2bin(p);
  391. if (tm->tm_year >= 50)
  392. tm->tm_year += 1900;
  393. else
  394. tm->tm_year += 2000;
  395. } else if (tag == ASN1_GENTIM) {
  396. /* GenTime: YYYYMMDDHHMMSSZ */
  397. if (vlen != 15)
  398. goto unsupported_time;
  399. tm->tm_year = DD2bin(p) * 100 + DD2bin(p);
  400. } else {
  401. goto unsupported_time;
  402. }
  403. tm->tm_year -= 1900;
  404. tm->tm_mon = DD2bin(p) - 1;
  405. tm->tm_mday = DD2bin(p);
  406. tm->tm_hour = DD2bin(p);
  407. tm->tm_min = DD2bin(p);
  408. tm->tm_sec = DD2bin(p);
  409. if (*p != 'Z')
  410. goto unsupported_time;
  411. return 0;
  412. unsupported_time:
  413. pr_debug("Got unsupported time [tag %02x]: '%*.*s'\n",
  414. tag, (int)vlen, (int)vlen, value);
  415. return -EBADMSG;
  416. }
  417. int x509_note_not_before(void *context, size_t hdrlen,
  418. unsigned char tag,
  419. const void *value, size_t vlen)
  420. {
  421. struct x509_parse_context *ctx = context;
  422. return x509_note_time(&ctx->cert->valid_from, hdrlen, tag, value, vlen);
  423. }
  424. int x509_note_not_after(void *context, size_t hdrlen,
  425. unsigned char tag,
  426. const void *value, size_t vlen)
  427. {
  428. struct x509_parse_context *ctx = context;
  429. return x509_note_time(&ctx->cert->valid_to, hdrlen, tag, value, vlen);
  430. }