You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

x509.c 37KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  1. /*
  2. * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. FILE_LICENCE ( GPL2_OR_LATER );
  19. #include <string.h>
  20. #include <ctype.h>
  21. #include <time.h>
  22. #include <errno.h>
  23. #include <assert.h>
  24. #include <ipxe/asn1.h>
  25. #include <ipxe/crypto.h>
  26. #include <ipxe/md5.h>
  27. #include <ipxe/sha1.h>
  28. #include <ipxe/sha256.h>
  29. #include <ipxe/rsa.h>
  30. #include <ipxe/rootcert.h>
  31. #include <ipxe/x509.h>
  32. /** @file
  33. *
  34. * X.509 certificates
  35. *
  36. * The structure of X.509v3 certificates is documented in RFC 5280
  37. * section 4.1.
  38. */
  39. /* Disambiguate the various error causes */
  40. #define ENOTSUP_ALGORITHM \
  41. __einfo_error ( EINFO_ENOTSUP_ALGORITHM )
  42. #define EINFO_ENOTSUP_ALGORITHM \
  43. __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )
  44. #define ENOTSUP_EXTENSION \
  45. __einfo_error ( EINFO_ENOTSUP_EXTENSION )
  46. #define EINFO_ENOTSUP_EXTENSION \
  47. __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported extension" )
  48. #define EINVAL_ALGORITHM \
  49. __einfo_error ( EINFO_EINVAL_ALGORITHM )
  50. #define EINFO_EINVAL_ALGORITHM \
  51. __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid algorithm type" )
  52. #define EINVAL_BIT_STRING \
  53. __einfo_error ( EINFO_EINVAL_BIT_STRING )
  54. #define EINFO_EINVAL_BIT_STRING \
  55. __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid bit string" )
  56. #define EINVAL_TIME \
  57. __einfo_error ( EINFO_EINVAL_TIME )
  58. #define EINFO_EINVAL_TIME \
  59. __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid time" )
  60. #define EINVAL_ALGORITHM_MISMATCH \
  61. __einfo_error ( EINFO_EINVAL_ALGORITHM_MISMATCH )
  62. #define EINFO_EINVAL_ALGORITHM_MISMATCH \
  63. __einfo_uniqify ( EINFO_EINVAL, 0x04, "Signature algorithm mismatch" )
  64. #define EINVAL_PATH_LEN \
  65. __einfo_error ( EINFO_EINVAL_PATH_LEN )
  66. #define EINFO_EINVAL_PATH_LEN \
  67. __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid pathLenConstraint" )
  68. #define EINVAL_VERSION \
  69. __einfo_error ( EINFO_EINVAL_VERSION )
  70. #define EINFO_EINVAL_VERSION \
  71. __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid version" )
  72. #define EACCES_WRONG_ISSUER \
  73. __einfo_error ( EINFO_EACCES_WRONG_ISSUER )
  74. #define EINFO_EACCES_WRONG_ISSUER \
  75. __einfo_uniqify ( EINFO_EACCES, 0x01, "Wrong issuer" )
  76. #define EACCES_NOT_CA \
  77. __einfo_error ( EINFO_EACCES_NOT_CA )
  78. #define EINFO_EACCES_NOT_CA \
  79. __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a CA certificate" )
  80. #define EACCES_KEY_USAGE \
  81. __einfo_error ( EINFO_EACCES_KEY_USAGE )
  82. #define EINFO_EACCES_KEY_USAGE \
  83. __einfo_uniqify ( EINFO_EACCES, 0x03, "Incorrect key usage" )
  84. #define EACCES_EXPIRED \
  85. __einfo_error ( EINFO_EACCES_EXPIRED )
  86. #define EINFO_EACCES_EXPIRED \
  87. __einfo_uniqify ( EINFO_EACCES, 0x04, "Expired (or not yet valid)" )
  88. #define EACCES_PATH_LEN \
  89. __einfo_error ( EINFO_EACCES_PATH_LEN )
  90. #define EINFO_EACCES_PATH_LEN \
  91. __einfo_uniqify ( EINFO_EACCES, 0x05, "Maximum path length exceeded" )
  92. #define EACCES_UNTRUSTED \
  93. __einfo_error ( EINFO_EACCES_UNTRUSTED )
  94. #define EINFO_EACCES_UNTRUSTED \
  95. __einfo_uniqify ( EINFO_EACCES, 0x06, "Untrusted root certificate" )
  96. /** "commonName" object identifier */
  97. static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
  98. /** "commonName" object identifier cursor */
  99. static struct asn1_cursor oid_common_name_cursor =
  100. ASN1_OID_CURSOR ( oid_common_name );
  101. /**
  102. * Parse X.509 certificate algorithm
  103. *
  104. * @v cert X.509 certificate
  105. * @v algorithm Algorithm to fill in
  106. * @v raw ASN.1 cursor
  107. * @ret rc Return status code
  108. */
  109. int x509_parse_pubkey_algorithm ( struct x509_certificate *cert,
  110. struct asn1_algorithm **algorithm,
  111. const struct asn1_cursor *raw ) {
  112. /* Parse algorithm */
  113. *algorithm = asn1_algorithm ( raw );
  114. if ( ! (*algorithm) ) {
  115. DBGC ( cert, "X509 %p unrecognised algorithm:\n", cert );
  116. DBGC_HDA ( cert, 0, raw->data, raw->len );
  117. return -ENOTSUP_ALGORITHM;
  118. }
  119. /* Check algorithm has a public key */
  120. if ( ! (*algorithm)->pubkey ) {
  121. DBGC ( cert, "X509 %p algorithm %s is not a public-key "
  122. "algorithm:\n", cert, (*algorithm)->name );
  123. DBGC_HDA ( cert, 0, raw->data, raw->len );
  124. return -EINVAL_ALGORITHM;
  125. }
  126. return 0;
  127. }
  128. /**
  129. * Parse X.509 certificate signature algorithm
  130. *
  131. * @v cert X.509 certificate
  132. * @v algorithm Algorithm to fill in
  133. * @v raw ASN.1 cursor
  134. * @ret rc Return status code
  135. */
  136. static int x509_parse_signature_algorithm ( struct x509_certificate *cert,
  137. struct asn1_algorithm **algorithm,
  138. const struct asn1_cursor *raw ) {
  139. int rc;
  140. /* Parse algorithm */
  141. if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
  142. raw ) ) != 0 )
  143. return rc;
  144. /* Check algorithm is a signature algorithm */
  145. if ( ! (*algorithm)->digest ) {
  146. DBGC ( cert, "X509 %p algorithm %s is not a signature "
  147. "algorithm:\n", cert, (*algorithm)->name );
  148. DBGC_HDA ( cert, 0, raw->data, raw->len );
  149. return -EINVAL_ALGORITHM;
  150. }
  151. return 0;
  152. }
  153. /**
  154. * Parse X.509 certificate bit string
  155. *
  156. * @v cert X.509 certificate
  157. * @v bits Bit string to fill in
  158. * @v raw ASN.1 cursor
  159. * @ret rc Return status code
  160. */
  161. static int x509_parse_bit_string ( struct x509_certificate *cert,
  162. struct x509_bit_string *bits,
  163. const struct asn1_cursor *raw ) {
  164. struct asn1_cursor cursor;
  165. const struct asn1_bit_string *bit_string;
  166. size_t len;
  167. unsigned int unused;
  168. uint8_t unused_mask;
  169. const uint8_t *last;
  170. int rc;
  171. /* Enter bit string */
  172. memcpy ( &cursor, raw, sizeof ( cursor ) );
  173. if ( ( rc = asn1_enter ( &cursor, ASN1_BIT_STRING ) ) != 0 ) {
  174. DBGC ( cert, "X509 %p cannot locate bit string:\n", cert );
  175. DBGC_HDA ( cert, 0, raw->data, raw->len );
  176. return rc;
  177. }
  178. /* Validity checks */
  179. if ( cursor.len < sizeof ( *bit_string ) ) {
  180. DBGC ( cert, "X509 %p invalid bit string:\n", cert );
  181. DBGC_HDA ( cert, 0, raw->data, raw->len );
  182. return -EINVAL_BIT_STRING;
  183. }
  184. bit_string = cursor.data;
  185. len = ( cursor.len - offsetof ( typeof ( *bit_string ), data ) );
  186. unused = bit_string->unused;
  187. unused_mask = ( 0xff >> ( 8 - unused ) );
  188. last = ( bit_string->data + len - 1 );
  189. if ( ( unused >= 8 ) ||
  190. ( ( unused > 0 ) && ( len == 0 ) ) ||
  191. ( ( *last & unused_mask ) != 0 ) ) {
  192. DBGC ( cert, "X509 %p invalid bit string:\n", cert );
  193. DBGC_HDA ( cert, 0, raw->data, raw->len );
  194. return -EINVAL_BIT_STRING;
  195. }
  196. /* Populate bit string */
  197. bits->data = &bit_string->data;
  198. bits->len = len;
  199. bits->unused = unused;
  200. return 0;
  201. }
  202. /**
  203. * Parse X.509 certificate bit string that must be an integral number of bytes
  204. *
  205. * @v cert X.509 certificate
  206. * @v bits Bit string to fill in
  207. * @v raw ASN.1 cursor
  208. * @ret rc Return status code
  209. */
  210. static int x509_parse_integral_bit_string ( struct x509_certificate *cert,
  211. struct x509_bit_string *bits,
  212. const struct asn1_cursor *raw ) {
  213. int rc;
  214. /* Parse bit string */
  215. if ( ( rc = x509_parse_bit_string ( cert, bits, raw ) ) != 0 )
  216. return rc;
  217. /* Check that there are no unused bits at end of string */
  218. if ( bits->unused ) {
  219. DBGC ( cert, "X509 %p invalid integral bit string:\n", cert );
  220. DBGC_HDA ( cert, 0, raw->data, raw->len );
  221. return -EINVAL_BIT_STRING;
  222. }
  223. return 0;
  224. }
  225. /**
  226. * Parse X.509 certificate time
  227. *
  228. * @v cert X.509 certificate
  229. * @v time Time to fill in
  230. * @v raw ASN.1 cursor
  231. * @ret rc Return status code
  232. *
  233. * RFC 5280 section 4.1.2.5 places several restrictions on the allowed
  234. * formats for UTCTime and GeneralizedTime, and mandates the
  235. * interpretation of centuryless year values.
  236. */
  237. static int x509_parse_time ( struct x509_certificate *cert,
  238. struct x509_time *time,
  239. const struct asn1_cursor *raw ) {
  240. struct asn1_cursor cursor;
  241. unsigned int have_century;
  242. unsigned int type;
  243. union {
  244. struct {
  245. uint8_t century;
  246. uint8_t year;
  247. uint8_t month;
  248. uint8_t day;
  249. uint8_t hour;
  250. uint8_t minute;
  251. uint8_t second;
  252. } __attribute__ (( packed )) named;
  253. uint8_t raw[7];
  254. } pairs;
  255. struct tm tm;
  256. const uint8_t *data;
  257. size_t remaining;
  258. unsigned int tens;
  259. unsigned int units;
  260. unsigned int i;
  261. int rc;
  262. /* Determine time format utcTime/generalizedTime */
  263. memcpy ( &cursor, raw, sizeof ( cursor ) );
  264. type = asn1_type ( &cursor );
  265. switch ( type ) {
  266. case ASN1_UTC_TIME:
  267. have_century = 0;
  268. break;
  269. case ASN1_GENERALIZED_TIME:
  270. have_century = 1;
  271. break;
  272. default:
  273. DBGC ( cert, "X509 %p invalid time type %02x\n", cert, type );
  274. DBGC_HDA ( cert, 0, raw->data, raw->len );
  275. return -EINVAL_TIME;
  276. }
  277. /* Enter utcTime/generalizedTime */
  278. if ( ( rc = asn1_enter ( &cursor, type ) ) != 0 ) {
  279. DBGC ( cert, "X509 %p cannot locate %s time:\n", cert,
  280. ( ( type == ASN1_UTC_TIME ) ? "UTC" : "generalized" ) );
  281. DBGC_HDA ( cert, 0, raw->data, raw->len );
  282. return rc;
  283. }
  284. /* Parse digit string a pair at a time */
  285. data = cursor.data;
  286. remaining = cursor.len;
  287. for ( i = ( have_century ? 0 : 1 ) ; i < sizeof ( pairs.raw ) ; i++ ) {
  288. if ( remaining < 2 ) {
  289. DBGC ( cert, "X509 %p invalid time:\n", cert );
  290. DBGC_HDA ( cert, 0, raw->data, raw->len );
  291. return -EINVAL_TIME;
  292. }
  293. tens = data[0];
  294. units = data[1];
  295. if ( ! ( isdigit ( tens ) && isdigit ( units ) ) ) {
  296. DBGC ( cert, "X509 %p invalid time:\n", cert );
  297. DBGC_HDA ( cert, 0, raw->data, raw->len );
  298. return -EINVAL_TIME;
  299. }
  300. pairs.raw[i] = ( ( 10 * ( tens - '0' ) ) + ( units - '0' ) );
  301. data += 2;
  302. remaining -= 2;
  303. }
  304. /* Determine century if applicable */
  305. if ( ! have_century )
  306. pairs.named.century = ( ( pairs.named.year >= 50 ) ? 19 : 20 );
  307. /* Check for trailing "Z" */
  308. if ( ( remaining != 1 ) || ( data[0] != 'Z' ) ) {
  309. DBGC ( cert, "X509 %p invalid time:\n", cert );
  310. DBGC_HDA ( cert, 0, raw->data, raw->len );
  311. return -EINVAL_TIME;
  312. }
  313. /* Fill in time */
  314. tm.tm_year = ( ( ( pairs.named.century - 19 ) * 100 ) +
  315. pairs.named.year );
  316. tm.tm_mon = ( pairs.named.month - 1 );
  317. tm.tm_mday = pairs.named.day;
  318. tm.tm_hour = pairs.named.hour;
  319. tm.tm_min = pairs.named.minute;
  320. tm.tm_sec = pairs.named.second;
  321. /* Convert to seconds since the Epoch */
  322. time->time = mktime ( &tm );
  323. return 0;
  324. }
  325. /**
  326. * Parse X.509 certificate version
  327. *
  328. * @v cert X.509 certificate
  329. * @v raw ASN.1 cursor
  330. * @ret rc Return status code
  331. */
  332. static int x509_parse_version ( struct x509_certificate *cert,
  333. const struct asn1_cursor *raw ) {
  334. struct asn1_cursor cursor;
  335. int version;
  336. int rc;
  337. /* Enter version */
  338. memcpy ( &cursor, raw, sizeof ( cursor ) );
  339. asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
  340. /* Parse integer */
  341. if ( ( rc = asn1_integer ( &cursor, &version ) ) != 0 ) {
  342. DBGC ( cert, "X509 %p cannot parse version: %s\n",
  343. cert, strerror ( rc ) );
  344. DBGC_HDA ( cert, 0, raw->data, raw->len );
  345. return rc;
  346. }
  347. /* Sanity check */
  348. if ( version < 0 ) {
  349. DBGC ( cert, "X509 %p invalid version %d\n", cert, version );
  350. DBGC_HDA ( cert, 0, raw->data, raw->len );
  351. return -EINVAL_VERSION;
  352. }
  353. /* Record version */
  354. cert->version = version;
  355. DBGC ( cert, "X509 %p is a version %d certificate\n",
  356. cert, ( cert->version + 1 ) );
  357. return 0;
  358. }
  359. /**
  360. * Parse X.509 certificate serial number
  361. *
  362. * @v cert X.509 certificate
  363. * @v raw ASN.1 cursor
  364. * @ret rc Return status code
  365. */
  366. static int x509_parse_serial ( struct x509_certificate *cert,
  367. const struct asn1_cursor *raw ) {
  368. struct x509_serial *serial = &cert->serial;
  369. int rc;
  370. /* Record raw serial number */
  371. memcpy ( &serial->raw, raw, sizeof ( serial->raw ) );
  372. if ( ( rc = asn1_shrink ( &serial->raw, ASN1_INTEGER ) ) != 0 ) {
  373. DBGC ( cert, "X509 %p cannot shrink serialNumber: %s\n",
  374. cert, strerror ( rc ) );
  375. return rc;
  376. }
  377. DBGC ( cert, "X509 %p issuer is:\n", cert );
  378. DBGC_HDA ( cert, 0, serial->raw.data, serial->raw.len );
  379. return 0;
  380. }
  381. /**
  382. * Parse X.509 certificate issuer
  383. *
  384. * @v cert X.509 certificate
  385. * @v raw ASN.1 cursor
  386. * @ret rc Return status code
  387. */
  388. static int x509_parse_issuer ( struct x509_certificate *cert,
  389. const struct asn1_cursor *raw ) {
  390. struct x509_issuer *issuer = &cert->issuer;
  391. int rc;
  392. /* Record raw issuer */
  393. memcpy ( &issuer->raw, raw, sizeof ( issuer->raw ) );
  394. if ( ( rc = asn1_shrink ( &issuer->raw, ASN1_SEQUENCE ) ) != 0 ) {
  395. DBGC ( cert, "X509 %p cannot shrink issuer: %s\n",
  396. cert, strerror ( rc ) );
  397. return rc;
  398. }
  399. DBGC ( cert, "X509 %p issuer is:\n", cert );
  400. DBGC_HDA ( cert, 0, issuer->raw.data, issuer->raw.len );
  401. return 0;
  402. }
  403. /**
  404. * Parse X.509 certificate validity
  405. *
  406. * @v cert X.509 certificate
  407. * @v raw ASN.1 cursor
  408. * @ret rc Return status code
  409. */
  410. static int x509_parse_validity ( struct x509_certificate *cert,
  411. const struct asn1_cursor *raw ) {
  412. struct x509_validity *validity = &cert->validity;
  413. struct x509_time *not_before = &validity->not_before;
  414. struct x509_time *not_after = &validity->not_after;
  415. struct asn1_cursor cursor;
  416. int rc;
  417. /* Enter validity */
  418. memcpy ( &cursor, raw, sizeof ( cursor ) );
  419. asn1_enter ( &cursor, ASN1_SEQUENCE );
  420. /* Parse notBefore */
  421. if ( ( rc = x509_parse_time ( cert, not_before, &cursor ) ) != 0 )
  422. return rc;
  423. DBGC ( cert, "X509 %p valid from time %lld\n", cert, not_before->time );
  424. asn1_skip_any ( &cursor );
  425. /* Parse notAfter */
  426. if ( ( rc = x509_parse_time ( cert, not_after, &cursor ) ) != 0 )
  427. return rc;
  428. DBGC ( cert, "X509 %p valid until time %lld\n", cert, not_after->time );
  429. return 0;
  430. }
  431. /**
  432. * Parse X.509 certificate common name
  433. *
  434. * @v cert X.509 certificate
  435. * @v name Common name to fill in
  436. * @v raw ASN.1 cursor
  437. * @ret rc Return status code
  438. */
  439. static int x509_parse_common_name ( struct x509_certificate *cert,
  440. struct x509_name *name,
  441. const struct asn1_cursor *raw ) {
  442. struct asn1_cursor cursor;
  443. struct asn1_cursor oid_cursor;
  444. struct asn1_cursor name_cursor;
  445. int rc;
  446. /* Enter name */
  447. memcpy ( &cursor, raw, sizeof ( cursor ) );
  448. asn1_enter ( &cursor, ASN1_SEQUENCE );
  449. /* Scan through name list */
  450. for ( ; cursor.len ; asn1_skip_any ( &cursor ) ) {
  451. memcpy ( &oid_cursor, &cursor, sizeof ( oid_cursor ) );
  452. asn1_enter ( &oid_cursor, ASN1_SET );
  453. asn1_enter ( &oid_cursor, ASN1_SEQUENCE );
  454. memcpy ( &name_cursor, &oid_cursor, sizeof ( name_cursor ) );
  455. asn1_enter ( &oid_cursor, ASN1_OID );
  456. if ( asn1_compare ( &oid_common_name_cursor, &oid_cursor ) != 0)
  457. continue;
  458. asn1_skip_any ( &name_cursor );
  459. if ( ( rc = asn1_enter_any ( &name_cursor ) ) != 0 ) {
  460. DBGC ( cert, "X509 %p cannot locate name:\n", cert );
  461. DBGC_HDA ( cert, 0, raw->data, raw->len );
  462. return rc;
  463. }
  464. name->data = name_cursor.data;
  465. name->len = name_cursor.len;
  466. return 0;
  467. }
  468. DBGC ( cert, "X509 %p no commonName found:\n", cert );
  469. DBGC_HDA ( cert, 0, raw->data, raw->len );
  470. return -ENOENT;
  471. }
  472. /**
  473. * Parse X.509 certificate subject
  474. *
  475. * @v cert X.509 certificate
  476. * @v raw ASN.1 cursor
  477. * @ret rc Return status code
  478. */
  479. static int x509_parse_subject ( struct x509_certificate *cert,
  480. const struct asn1_cursor *raw ) {
  481. struct x509_subject *subject = &cert->subject;
  482. struct x509_name *name = &subject->name;
  483. int rc;
  484. /* Record raw subject */
  485. memcpy ( &subject->raw, raw, sizeof ( subject->raw ) );
  486. asn1_shrink_any ( &subject->raw );
  487. DBGC ( cert, "X509 %p subject is:\n", cert );
  488. DBGC_HDA ( cert, 0, subject->raw.data, subject->raw.len );
  489. /* Parse common name */
  490. if ( ( rc = x509_parse_common_name ( cert, name, raw ) ) != 0 )
  491. return rc;
  492. DBGC ( cert, "X509 %p common name is:\n", cert );
  493. DBGC_HDA ( cert, 0, name->data, name->len );
  494. return 0;
  495. }
  496. /**
  497. * Parse X.509 certificate public key information
  498. *
  499. * @v cert X.509 certificate
  500. * @v raw ASN.1 cursor
  501. * @ret rc Return status code
  502. */
  503. static int x509_parse_public_key ( struct x509_certificate *cert,
  504. const struct asn1_cursor *raw ) {
  505. struct x509_public_key *public_key = &cert->subject.public_key;
  506. struct asn1_algorithm **algorithm = &public_key->algorithm;
  507. struct asn1_cursor cursor;
  508. int rc;
  509. /* Record raw subjectPublicKeyInfo */
  510. memcpy ( &cursor, raw, sizeof ( cursor ) );
  511. asn1_shrink_any ( &cursor );
  512. memcpy ( &public_key->raw, &cursor, sizeof ( public_key->raw ) );
  513. /* Enter subjectPublicKeyInfo */
  514. asn1_enter ( &cursor, ASN1_SEQUENCE );
  515. /* Parse algorithm */
  516. if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
  517. &cursor ) ) != 0 )
  518. return rc;
  519. DBGC ( cert, "X509 %p public key algorithm is %s\n",
  520. cert, (*algorithm)->name );
  521. DBGC ( cert, "X509 %p public key is:\n", cert );
  522. DBGC_HDA ( cert, 0, public_key->raw.data, public_key->raw.len );
  523. return 0;
  524. }
  525. /**
  526. * Parse X.509 certificate basic constraints
  527. *
  528. * @v cert X.509 certificate
  529. * @v raw ASN.1 cursor
  530. * @ret rc Return status code
  531. */
  532. static int x509_parse_basic_constraints ( struct x509_certificate *cert,
  533. const struct asn1_cursor *raw ) {
  534. struct x509_basic_constraints *basic = &cert->extensions.basic;
  535. struct asn1_cursor cursor;
  536. int ca = 0;
  537. int path_len;
  538. int rc;
  539. /* Enter basicConstraints */
  540. memcpy ( &cursor, raw, sizeof ( cursor ) );
  541. asn1_enter ( &cursor, ASN1_SEQUENCE );
  542. /* Parse "cA", if present */
  543. if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
  544. ca = asn1_boolean ( &cursor );
  545. if ( ca < 0 ) {
  546. rc = ca;
  547. DBGC ( cert, "X509 %p cannot parse cA: %s\n",
  548. cert, strerror ( rc ) );
  549. DBGC_HDA ( cert, 0, raw->data, raw->len );
  550. return rc;
  551. }
  552. asn1_skip_any ( &cursor );
  553. }
  554. basic->ca = ca;
  555. DBGC ( cert, "X509 %p is %sa CA certificate\n",
  556. cert, ( basic->ca ? "" : "not " ) );
  557. /* Ignore everything else unless "cA" is true */
  558. if ( ! ca )
  559. return 0;
  560. /* Parse "pathLenConstraint", if present and applicable */
  561. basic->path_len = -1U; /* Default is unlimited */
  562. if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
  563. if ( ( rc = asn1_integer ( &cursor, &path_len ) ) != 0 ) {
  564. DBGC ( cert, "X509 %p cannot parse pathLenConstraint: "
  565. "%s\n", cert, strerror ( rc ) );
  566. DBGC_HDA ( cert, 0, raw->data, raw->len );
  567. return rc;
  568. }
  569. if ( path_len < 0 ) {
  570. DBGC ( cert, "X509 %p invalid pathLenConstraint %d\n",
  571. cert, path_len );
  572. DBGC_HDA ( cert, 0, raw->data, raw->len );
  573. return -EINVAL;
  574. }
  575. basic->path_len = path_len;
  576. DBGC ( cert, "X509 %p path length constraint is %u\n",
  577. cert, basic->path_len );
  578. }
  579. return 0;
  580. }
  581. /**
  582. * Parse X.509 certificate key usage
  583. *
  584. * @v cert X.509 certificate
  585. * @v raw ASN.1 cursor
  586. * @ret rc Return status code
  587. */
  588. static int x509_parse_key_usage ( struct x509_certificate *cert,
  589. const struct asn1_cursor *raw ) {
  590. struct x509_key_usage *usage = &cert->extensions.usage;
  591. struct x509_bit_string bit_string;
  592. const uint8_t *bytes;
  593. size_t len;
  594. unsigned int i;
  595. int rc;
  596. /* Mark extension as present */
  597. usage->present = 1;
  598. /* Parse bit string */
  599. if ( ( rc = x509_parse_bit_string ( cert, &bit_string, raw ) ) != 0 )
  600. return rc;
  601. /* Parse key usage bits */
  602. bytes = bit_string.data;
  603. len = bit_string.len;
  604. if ( len > sizeof ( usage->bits ) )
  605. len = sizeof ( usage->bits );
  606. for ( i = 0 ; i < len ; i++ ) {
  607. usage->bits |= ( *(bytes++) << ( 8 * i ) );
  608. }
  609. DBGC ( cert, "X509 %p key usage is %08x\n", cert, usage->bits );
  610. return 0;
  611. }
  612. /** "id-kp-codeSigning" object identifier */
  613. static uint8_t oid_code_signing[] = { ASN1_OID_CODESIGNING };
  614. /** Supported key purposes */
  615. static struct x509_key_purpose x509_key_purposes[] = {
  616. {
  617. .name = "codeSigning",
  618. .bits = X509_CODE_SIGNING,
  619. .oid = ASN1_OID_CURSOR ( oid_code_signing ),
  620. },
  621. };
  622. /**
  623. * Parse X.509 certificate key purpose identifier
  624. *
  625. * @v cert X.509 certificate
  626. * @v raw ASN.1 cursor
  627. * @ret rc Return status code
  628. */
  629. static int x509_parse_key_purpose ( struct x509_certificate *cert,
  630. const struct asn1_cursor *raw ) {
  631. struct x509_extended_key_usage *ext_usage = &cert->extensions.ext_usage;
  632. struct x509_key_purpose *purpose;
  633. struct asn1_cursor cursor;
  634. unsigned int i;
  635. int rc;
  636. /* Enter keyPurposeId */
  637. memcpy ( &cursor, raw, sizeof ( cursor ) );
  638. if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
  639. DBGC ( cert, "X509 %p invalid keyPurposeId:\n", cert );
  640. DBGC_HDA ( cert, 0, raw->data, raw->len );
  641. return rc;
  642. }
  643. /* Identify key purpose */
  644. for ( i = 0 ; i < ( sizeof ( x509_key_purposes ) /
  645. sizeof ( x509_key_purposes[0] ) ) ; i++ ) {
  646. purpose = &x509_key_purposes[i];
  647. if ( asn1_compare ( &cursor, &purpose->oid ) == 0 ) {
  648. DBGC ( cert, "X509 %p has key purpose %s\n",
  649. cert, purpose->name );
  650. ext_usage->bits |= purpose->bits;
  651. return 0;
  652. }
  653. }
  654. /* Ignore unrecognised key purposes */
  655. return 0;
  656. }
  657. /**
  658. * Parse X.509 certificate extended key usage
  659. *
  660. * @v cert X.509 certificate
  661. * @v raw ASN.1 cursor
  662. * @ret rc Return status code
  663. */
  664. static int x509_parse_extended_key_usage ( struct x509_certificate *cert,
  665. const struct asn1_cursor *raw ) {
  666. struct asn1_cursor cursor;
  667. int rc;
  668. /* Enter extKeyUsage */
  669. memcpy ( &cursor, raw, sizeof ( cursor ) );
  670. asn1_enter ( &cursor, ASN1_SEQUENCE );
  671. /* Parse each extension in turn */
  672. while ( cursor.len ) {
  673. if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
  674. return rc;
  675. asn1_skip_any ( &cursor );
  676. }
  677. return 0;
  678. }
  679. /** "id-ce-basicConstraints" object identifier */
  680. static uint8_t oid_ce_basic_constraints[] = { ASN1_OID_BASICCONSTRAINTS };
  681. /** "id-ce-keyUsage" object identifier */
  682. static uint8_t oid_ce_key_usage[] = { ASN1_OID_KEYUSAGE };
  683. /** "id-ce-extKeyUsage" object identifier */
  684. static uint8_t oid_ce_ext_key_usage[] = { ASN1_OID_EXTKEYUSAGE };
  685. /** Supported certificate extensions */
  686. static struct x509_extension x509_extensions[] = {
  687. {
  688. .name = "basicConstraints",
  689. .oid = ASN1_OID_CURSOR ( oid_ce_basic_constraints ),
  690. .parse = x509_parse_basic_constraints,
  691. },
  692. {
  693. .name = "keyUsage",
  694. .oid = ASN1_OID_CURSOR ( oid_ce_key_usage ),
  695. .parse = x509_parse_key_usage,
  696. },
  697. {
  698. .name = "extKeyUsage",
  699. .oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
  700. .parse = x509_parse_extended_key_usage,
  701. },
  702. };
  703. /**
  704. * Identify X.509 extension by OID
  705. *
  706. * @v oid OID
  707. * @ret extension Extension, or NULL
  708. */
  709. static struct x509_extension *
  710. x509_find_extension ( const struct asn1_cursor *oid ) {
  711. struct x509_extension *extension;
  712. unsigned int i;
  713. for ( i = 0 ; i < ( sizeof ( x509_extensions ) /
  714. sizeof ( x509_extensions[0] ) ) ; i++ ) {
  715. extension = &x509_extensions[i];
  716. if ( asn1_compare ( &extension->oid, oid ) == 0 )
  717. return extension;
  718. }
  719. return NULL;
  720. }
  721. /**
  722. * Parse X.509 certificate extension
  723. *
  724. * @v cert X.509 certificate
  725. * @v raw ASN.1 cursor
  726. * @ret rc Return status code
  727. */
  728. static int x509_parse_extension ( struct x509_certificate *cert,
  729. const struct asn1_cursor *raw ) {
  730. struct asn1_cursor cursor;
  731. struct asn1_cursor subcursor;
  732. struct x509_extension *extension;
  733. int is_critical = 0;
  734. int rc;
  735. /* Enter extension */
  736. memcpy ( &cursor, raw, sizeof ( cursor ) );
  737. asn1_enter ( &cursor, ASN1_SEQUENCE );
  738. /* Try to identify extension */
  739. memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
  740. asn1_enter ( &subcursor, ASN1_OID );
  741. extension = x509_find_extension ( &subcursor );
  742. asn1_skip_any ( &cursor );
  743. DBGC ( cert, "X509 %p found extension %s\n",
  744. cert, ( extension ? extension->name : "<unknown>" ) );
  745. /* Identify criticality */
  746. if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
  747. is_critical = asn1_boolean ( &cursor );
  748. if ( is_critical < 0 ) {
  749. rc = is_critical;
  750. DBGC ( cert, "X509 %p cannot parse extension "
  751. "criticality: %s\n", cert, strerror ( rc ) );
  752. DBGC_HDA ( cert, 0, raw->data, raw->len );
  753. return rc;
  754. }
  755. asn1_skip_any ( &cursor );
  756. }
  757. /* Handle unknown extensions */
  758. if ( ! extension ) {
  759. if ( is_critical ) {
  760. /* Fail if we cannot handle a critical extension */
  761. DBGC ( cert, "X509 %p cannot handle critical "
  762. "extension:\n", cert );
  763. DBGC_HDA ( cert, 0, raw->data, raw->len );
  764. return -ENOTSUP_EXTENSION;
  765. } else {
  766. /* Ignore unknown non-critical extensions */
  767. return 0;
  768. }
  769. };
  770. /* Extract extnValue */
  771. if ( ( rc = asn1_enter ( &cursor, ASN1_OCTET_STRING ) ) != 0 ) {
  772. DBGC ( cert, "X509 %p extension missing extnValue:\n", cert );
  773. DBGC_HDA ( cert, 0, raw->data, raw->len );
  774. return rc;
  775. }
  776. /* Parse extension */
  777. if ( ( rc = extension->parse ( cert, &cursor ) ) != 0 )
  778. return rc;
  779. return 0;
  780. }
  781. /**
  782. * Parse X.509 certificate extensions, if present
  783. *
  784. * @v cert X.509 certificate
  785. * @v raw ASN.1 cursor
  786. * @ret rc Return status code
  787. */
  788. static int x509_parse_extensions ( struct x509_certificate *cert,
  789. const struct asn1_cursor *raw ) {
  790. struct asn1_cursor cursor;
  791. int rc;
  792. /* Enter extensions, if present */
  793. memcpy ( &cursor, raw, sizeof ( cursor ) );
  794. asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 3 ) );
  795. asn1_enter ( &cursor, ASN1_SEQUENCE );
  796. /* Parse each extension in turn */
  797. while ( cursor.len ) {
  798. if ( ( rc = x509_parse_extension ( cert, &cursor ) ) != 0 )
  799. return rc;
  800. asn1_skip_any ( &cursor );
  801. }
  802. return 0;
  803. }
  804. /**
  805. * Parse X.509 certificate tbsCertificate
  806. *
  807. * @v cert X.509 certificate
  808. * @v raw ASN.1 cursor
  809. * @ret rc Return status code
  810. */
  811. static int x509_parse_tbscertificate ( struct x509_certificate *cert,
  812. const struct asn1_cursor *raw ) {
  813. struct asn1_algorithm **algorithm = &cert->signature_algorithm;
  814. struct asn1_cursor cursor;
  815. int rc;
  816. /* Record raw tbsCertificate */
  817. memcpy ( &cursor, raw, sizeof ( cursor ) );
  818. asn1_shrink_any ( &cursor );
  819. memcpy ( &cert->tbs, &cursor, sizeof ( cert->tbs ) );
  820. /* Enter tbsCertificate */
  821. asn1_enter ( &cursor, ASN1_SEQUENCE );
  822. /* Parse version, if present */
  823. if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
  824. if ( ( rc = x509_parse_version ( cert, &cursor ) ) != 0 )
  825. return rc;
  826. asn1_skip_any ( &cursor );
  827. }
  828. /* Parse serialNumber */
  829. if ( ( rc = x509_parse_serial ( cert, &cursor ) ) != 0 )
  830. return rc;
  831. asn1_skip_any ( &cursor );
  832. /* Parse signature */
  833. if ( ( rc = x509_parse_signature_algorithm ( cert, algorithm,
  834. &cursor ) ) != 0 )
  835. return rc;
  836. DBGC ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
  837. cert, (*algorithm)->name );
  838. asn1_skip_any ( &cursor );
  839. /* Parse issuer */
  840. if ( ( rc = x509_parse_issuer ( cert, &cursor ) ) != 0 )
  841. return rc;
  842. asn1_skip_any ( &cursor );
  843. /* Parse validity */
  844. if ( ( rc = x509_parse_validity ( cert, &cursor ) ) != 0 )
  845. return rc;
  846. asn1_skip_any ( &cursor );
  847. /* Parse subject */
  848. if ( ( rc = x509_parse_subject ( cert, &cursor ) ) != 0 )
  849. return rc;
  850. asn1_skip_any ( &cursor );
  851. /* Parse subjectPublicKeyInfo */
  852. if ( ( rc = x509_parse_public_key ( cert, &cursor ) ) != 0 )
  853. return rc;
  854. asn1_skip_any ( &cursor );
  855. /* Parse extensions, if present */
  856. if ( ( rc = x509_parse_extensions ( cert, &cursor ) ) != 0 )
  857. return rc;
  858. return 0;
  859. }
  860. /**
  861. * Parse X.509 certificate from ASN.1 data
  862. *
  863. * @v cert X.509 certificate
  864. * @v data Raw certificate data
  865. * @v len Length of raw data
  866. * @ret rc Return status code
  867. */
  868. int x509_parse ( struct x509_certificate *cert, const void *data, size_t len ) {
  869. struct x509_signature *signature = &cert->signature;
  870. struct asn1_algorithm **signature_algorithm = &signature->algorithm;
  871. struct x509_bit_string *signature_value = &signature->value;
  872. struct asn1_cursor cursor;
  873. int rc;
  874. /* Initialise certificate */
  875. memset ( cert, 0, sizeof ( *cert ) );
  876. cert->raw.data = data;
  877. cert->raw.len = len;
  878. asn1_shrink_any ( &cert->raw );
  879. /* Enter certificate */
  880. memcpy ( &cursor, &cert->raw, sizeof ( cursor ) );
  881. asn1_enter ( &cursor, ASN1_SEQUENCE );
  882. /* Parse tbsCertificate */
  883. if ( ( rc = x509_parse_tbscertificate ( cert, &cursor ) ) != 0 )
  884. return rc;
  885. asn1_skip_any ( &cursor );
  886. /* Parse signatureAlgorithm */
  887. if ( ( rc = x509_parse_signature_algorithm ( cert, signature_algorithm,
  888. &cursor ) ) != 0 )
  889. return rc;
  890. DBGC ( cert, "X509 %p signatureAlgorithm is %s\n",
  891. cert, (*signature_algorithm)->name );
  892. asn1_skip_any ( &cursor );
  893. /* Parse signatureValue */
  894. if ( ( rc = x509_parse_integral_bit_string ( cert, signature_value,
  895. &cursor ) ) != 0 )
  896. return rc;
  897. DBGC ( cert, "X509 %p signatureValue is:\n", cert );
  898. DBGC_HDA ( cert, 0, signature_value->data, signature_value->len );
  899. /* Check that algorithm in tbsCertificate matches algorithm in
  900. * signature
  901. */
  902. if ( signature->algorithm != (*signature_algorithm) ) {
  903. DBGC ( cert, "X509 %p signature algorithm %s does not match "
  904. "signatureAlgorithm %s\n",
  905. cert, signature->algorithm->name,
  906. (*signature_algorithm)->name );
  907. return -EINVAL_ALGORITHM_MISMATCH;
  908. }
  909. return 0;
  910. }
  911. /**
  912. * Verify X.509 certificate signature
  913. *
  914. * @v cert X.509 certificate
  915. * @v public_key X.509 public key
  916. * @ret rc Return status code
  917. */
  918. static int x509_check_signature ( struct x509_certificate *cert,
  919. struct x509_public_key *public_key ) {
  920. struct x509_signature *signature = &cert->signature;
  921. struct asn1_algorithm *algorithm = signature->algorithm;
  922. struct digest_algorithm *digest = algorithm->digest;
  923. struct pubkey_algorithm *pubkey = algorithm->pubkey;
  924. uint8_t digest_ctx[ digest->ctxsize ];
  925. uint8_t digest_out[ digest->digestsize ];
  926. uint8_t pubkey_ctx[ pubkey->ctxsize ];
  927. int rc;
  928. /* Sanity check */
  929. assert ( cert->signature_algorithm == cert->signature.algorithm );
  930. /* Calculate certificate digest */
  931. digest_init ( digest, digest_ctx );
  932. digest_update ( digest, digest_ctx, cert->tbs.data, cert->tbs.len );
  933. digest_final ( digest, digest_ctx, digest_out );
  934. DBGC ( cert, "X509 %p digest:\n", cert );
  935. DBGC_HDA ( cert, 0, digest_out, sizeof ( digest_out ) );
  936. /* Check that signature public key algorithm matches signer */
  937. if ( public_key->algorithm->pubkey != pubkey ) {
  938. DBGC ( cert, "X509 %p signature algorithm %s does not match "
  939. "signer's algorithm %s\n",
  940. cert, algorithm->name, public_key->algorithm->name );
  941. rc = -EINVAL_ALGORITHM_MISMATCH;
  942. goto err_mismatch;
  943. }
  944. /* Verify signature using signer's public key */
  945. if ( ( rc = pubkey_init ( pubkey, pubkey_ctx, public_key->raw.data,
  946. public_key->raw.len ) ) != 0 ) {
  947. DBGC ( cert, "X509 %p cannot initialise public key: %s\n",
  948. cert, strerror ( rc ) );
  949. goto err_pubkey_init;
  950. }
  951. if ( ( rc = pubkey_verify ( pubkey, pubkey_ctx, digest, digest_out,
  952. signature->value.data,
  953. signature->value.len ) ) != 0 ) {
  954. DBGC ( cert, "X509 %p signature verification failed: %s\n",
  955. cert, strerror ( rc ) );
  956. goto err_pubkey_verify;
  957. }
  958. /* Success */
  959. rc = 0;
  960. err_pubkey_verify:
  961. pubkey_final ( pubkey, pubkey_ctx );
  962. err_pubkey_init:
  963. err_mismatch:
  964. return rc;
  965. }
  966. /**
  967. * Validate X.509 certificate against issuer certificate
  968. *
  969. * @v cert X.509 certificate
  970. * @v issuer X.509 issuer certificate
  971. * @ret rc Return status code
  972. */
  973. int x509_validate_issuer ( struct x509_certificate *cert,
  974. struct x509_certificate *issuer ) {
  975. struct x509_public_key *public_key = &issuer->subject.public_key;
  976. int rc;
  977. /* Check issuer. In theory, this should be a full X.500 DN
  978. * comparison, which would require support for a plethora of
  979. * abominations such as TeletexString (which allows the
  980. * character set to be changed mid-string using escape codes).
  981. * In practice, we assume that anyone who deliberately changes
  982. * the encoding of the issuer DN is probably a masochist who
  983. * will rather enjoy the process of figuring out exactly why
  984. * their certificate doesn't work.
  985. *
  986. * See http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
  987. * for some enjoyable ranting on this subject.
  988. */
  989. if ( asn1_compare ( &cert->issuer.raw, &issuer->subject.raw ) != 0 ) {
  990. DBGC ( cert, "X509 %p issuer does not match X509 %p subject\n",
  991. cert, issuer );
  992. DBGC_HDA ( cert, 0, cert->issuer.raw.data,
  993. cert->issuer.raw.len );
  994. DBGC_HDA ( issuer, 0, issuer->subject.raw.data,
  995. issuer->subject.raw.len );
  996. return -EACCES_WRONG_ISSUER;
  997. }
  998. /* Check that issuer is allowed to sign certificates */
  999. if ( ! issuer->extensions.basic.ca ) {
  1000. DBGC ( issuer, "X509 %p cannot sign X509 %p: not a CA "
  1001. "certificate\n", issuer, cert );
  1002. return -EACCES_NOT_CA;
  1003. }
  1004. if ( issuer->extensions.usage.present &&
  1005. ( ! ( issuer->extensions.usage.bits & X509_KEY_CERT_SIGN ) ) ) {
  1006. DBGC ( issuer, "X509 %p cannot sign X509 %p: no keyCertSign "
  1007. "usage\n", issuer, cert );
  1008. return -EACCES_KEY_USAGE;
  1009. }
  1010. /* Check signature */
  1011. if ( ( rc = x509_check_signature ( cert, public_key ) ) != 0 )
  1012. return rc;
  1013. DBGC ( cert, "X509 %p successfully validated using X509 %p\n",
  1014. cert, issuer );
  1015. return 0;
  1016. }
  1017. /**
  1018. * Calculate X.509 certificate fingerprint
  1019. *
  1020. * @v cert X.509 certificate
  1021. * @v digest Digest algorithm
  1022. * @v fingerprint Fingerprint buffer
  1023. */
  1024. void x509_fingerprint ( struct x509_certificate *cert,
  1025. struct digest_algorithm *digest, void *fingerprint ) {
  1026. uint8_t ctx[ digest->ctxsize ];
  1027. /* Calculate fingerprint */
  1028. digest_init ( digest, ctx );
  1029. digest_update ( digest, ctx, cert->raw.data, cert->raw.len );
  1030. digest_final ( digest, ctx, fingerprint );
  1031. }
  1032. /**
  1033. * Validate X.509 root certificate
  1034. *
  1035. * @v cert X.509 certificate
  1036. * @v root X.509 root certificate store
  1037. * @ret rc Return status code
  1038. */
  1039. int x509_validate_root ( struct x509_certificate *cert,
  1040. struct x509_root *root ) {
  1041. struct digest_algorithm *digest = root->digest;
  1042. uint8_t fingerprint[ digest->digestsize ];
  1043. const uint8_t *root_fingerprint = root->fingerprints;
  1044. unsigned int i;
  1045. /* Calculate certificate fingerprint */
  1046. x509_fingerprint ( cert, digest, fingerprint );
  1047. /* Check fingerprint against all root certificates */
  1048. for ( i = 0 ; i < root->count ; i++ ) {
  1049. if ( memcmp ( fingerprint, root_fingerprint,
  1050. sizeof ( fingerprint ) ) == 0 ) {
  1051. DBGC ( cert, "X509 %p is a root certificate\n", cert );
  1052. return 0;
  1053. }
  1054. root_fingerprint += sizeof ( fingerprint );
  1055. }
  1056. DBGC ( cert, "X509 %p is not a root certificate\n", cert );
  1057. return -ENOENT;
  1058. }
  1059. /**
  1060. * Validate X.509 certificate validity period
  1061. *
  1062. * @v cert X.509 certificate
  1063. * @v time Time at which to validate certificate
  1064. * @ret rc Return status code
  1065. */
  1066. int x509_validate_time ( struct x509_certificate *cert, time_t time ) {
  1067. struct x509_validity *validity = &cert->validity;
  1068. /* Check validity period */
  1069. if ( time < validity->not_before.time ) {
  1070. DBGC ( cert, "X509 %p is not yet valid (at time %lld)\n",
  1071. cert, time );
  1072. return -EACCES_EXPIRED;
  1073. }
  1074. if ( time > validity->not_after.time ) {
  1075. DBGC ( cert, "X509 %p has expired (at time %lld)\n",
  1076. cert, time );
  1077. return -EACCES_EXPIRED;
  1078. }
  1079. DBGC ( cert, "X509 %p is valid (at time %lld)\n", cert, time );
  1080. return 0;
  1081. }
  1082. /**
  1083. * Validate X.509 certificate chain
  1084. *
  1085. * @v parse_next Parse next X.509 certificate in chain
  1086. * @v context Context for parse_next()
  1087. * @v time Time at which to validate certificates
  1088. * @v root Root certificate store, or NULL to use default
  1089. * @v first Initial X.509 certificate to fill in, or NULL
  1090. * @ret rc Return status code
  1091. */
  1092. int x509_validate_chain ( int ( * parse_next )
  1093. ( struct x509_certificate *cert,
  1094. const struct x509_certificate *previous,
  1095. void *context ),
  1096. void *context, time_t time, struct x509_root *root,
  1097. struct x509_certificate *first ) {
  1098. struct x509_certificate temp[2];
  1099. struct x509_certificate *current = &temp[0];
  1100. struct x509_certificate *next = &temp[1];
  1101. struct x509_certificate *swap;
  1102. unsigned int path_len = 0;
  1103. int rc;
  1104. /* Use default root certificate store if none specified */
  1105. if ( ! root )
  1106. root = &root_certificates;
  1107. /* Get first certificate in chain */
  1108. if ( ( rc = parse_next ( current, NULL, context ) ) != 0 ) {
  1109. DBGC ( context, "X509 chain %p could not get first "
  1110. "certificate: %s\n", context, strerror ( rc ) );
  1111. return rc;
  1112. }
  1113. /* Record first certificate, if applicable */
  1114. if ( first )
  1115. memcpy ( first, current, sizeof ( *first ) );
  1116. /* Process chain */
  1117. while ( 1 ) {
  1118. /* Check that certificate is valid at specified time */
  1119. if ( ( rc = x509_validate_time ( current, time ) ) != 0 )
  1120. return rc;
  1121. /* Succeed if we have reached a trusted root certificate */
  1122. if ( x509_validate_root ( current, root ) == 0 )
  1123. return 0;
  1124. /* Fail if we have reached an untrusted root certificate */
  1125. if ( asn1_compare ( &current->issuer.raw,
  1126. &current->subject.raw ) == 0 ) {
  1127. DBGC ( context, "X509 chain %p reached untrusted root "
  1128. "certificate\n", context );
  1129. return -EACCES_UNTRUSTED;
  1130. }
  1131. /* Get next certificate in chain */
  1132. if ( ( rc = parse_next ( next, current, context ) ) != 0 ) {
  1133. DBGC ( context, "X509 chain %p could not get next "
  1134. "certificate: %s\n", context, strerror ( rc ) );
  1135. return rc;
  1136. }
  1137. /* Validate current certificate against next certificate */
  1138. if ( ( rc = x509_validate_issuer ( current, next ) ) != 0 )
  1139. return rc;
  1140. /* Validate path length constraint */
  1141. if ( path_len > next->extensions.basic.path_len ) {
  1142. DBGC ( context, "X509 chain %p path length %d exceeds "
  1143. "maximum %d\n", context, path_len,
  1144. next->extensions.basic.path_len );
  1145. return -EACCES_PATH_LEN;
  1146. }
  1147. path_len++;
  1148. /* Move to next certificate in chain */
  1149. swap = current;
  1150. current = next;
  1151. next = swap;
  1152. }
  1153. }