Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

x509.c 43KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587
  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., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. */
  19. FILE_LICENCE ( GPL2_OR_LATER );
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <errno.h>
  23. #include <assert.h>
  24. #include <ipxe/list.h>
  25. #include <ipxe/base16.h>
  26. #include <ipxe/asn1.h>
  27. #include <ipxe/crypto.h>
  28. #include <ipxe/md5.h>
  29. #include <ipxe/sha1.h>
  30. #include <ipxe/sha256.h>
  31. #include <ipxe/rsa.h>
  32. #include <ipxe/rootcert.h>
  33. #include <ipxe/certstore.h>
  34. #include <ipxe/x509.h>
  35. /** @file
  36. *
  37. * X.509 certificates
  38. *
  39. * The structure of X.509v3 certificates is documented in RFC 5280
  40. * section 4.1.
  41. */
  42. /* Disambiguate the various error causes */
  43. #define ENOTSUP_ALGORITHM \
  44. __einfo_error ( EINFO_ENOTSUP_ALGORITHM )
  45. #define EINFO_ENOTSUP_ALGORITHM \
  46. __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )
  47. #define ENOTSUP_EXTENSION \
  48. __einfo_error ( EINFO_ENOTSUP_EXTENSION )
  49. #define EINFO_ENOTSUP_EXTENSION \
  50. __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported extension" )
  51. #define EINVAL_ALGORITHM \
  52. __einfo_error ( EINFO_EINVAL_ALGORITHM )
  53. #define EINFO_EINVAL_ALGORITHM \
  54. __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid algorithm type" )
  55. #define EINVAL_ALGORITHM_MISMATCH \
  56. __einfo_error ( EINFO_EINVAL_ALGORITHM_MISMATCH )
  57. #define EINFO_EINVAL_ALGORITHM_MISMATCH \
  58. __einfo_uniqify ( EINFO_EINVAL, 0x04, "Signature algorithm mismatch" )
  59. #define EINVAL_PATH_LEN \
  60. __einfo_error ( EINFO_EINVAL_PATH_LEN )
  61. #define EINFO_EINVAL_PATH_LEN \
  62. __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid pathLenConstraint" )
  63. #define EINVAL_VERSION \
  64. __einfo_error ( EINFO_EINVAL_VERSION )
  65. #define EINFO_EINVAL_VERSION \
  66. __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid version" )
  67. #define EACCES_WRONG_ISSUER \
  68. __einfo_error ( EINFO_EACCES_WRONG_ISSUER )
  69. #define EINFO_EACCES_WRONG_ISSUER \
  70. __einfo_uniqify ( EINFO_EACCES, 0x01, "Wrong issuer" )
  71. #define EACCES_NOT_CA \
  72. __einfo_error ( EINFO_EACCES_NOT_CA )
  73. #define EINFO_EACCES_NOT_CA \
  74. __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a CA certificate" )
  75. #define EACCES_KEY_USAGE \
  76. __einfo_error ( EINFO_EACCES_KEY_USAGE )
  77. #define EINFO_EACCES_KEY_USAGE \
  78. __einfo_uniqify ( EINFO_EACCES, 0x03, "Incorrect key usage" )
  79. #define EACCES_EXPIRED \
  80. __einfo_error ( EINFO_EACCES_EXPIRED )
  81. #define EINFO_EACCES_EXPIRED \
  82. __einfo_uniqify ( EINFO_EACCES, 0x04, "Expired (or not yet valid)" )
  83. #define EACCES_PATH_LEN \
  84. __einfo_error ( EINFO_EACCES_PATH_LEN )
  85. #define EINFO_EACCES_PATH_LEN \
  86. __einfo_uniqify ( EINFO_EACCES, 0x05, "Maximum path length exceeded" )
  87. #define EACCES_UNTRUSTED \
  88. __einfo_error ( EINFO_EACCES_UNTRUSTED )
  89. #define EINFO_EACCES_UNTRUSTED \
  90. __einfo_uniqify ( EINFO_EACCES, 0x06, "Untrusted root certificate" )
  91. #define EACCES_OUT_OF_ORDER \
  92. __einfo_error ( EINFO_EACCES_OUT_OF_ORDER )
  93. #define EINFO_EACCES_OUT_OF_ORDER \
  94. __einfo_uniqify ( EINFO_EACCES, 0x07, "Validation out of order" )
  95. #define EACCES_EMPTY \
  96. __einfo_error ( EINFO_EACCES_EMPTY )
  97. #define EINFO_EACCES_EMPTY \
  98. __einfo_uniqify ( EINFO_EACCES, 0x08, "Empty certificate chain" )
  99. #define EACCES_OCSP_REQUIRED \
  100. __einfo_error ( EINFO_EACCES_OCSP_REQUIRED )
  101. #define EINFO_EACCES_OCSP_REQUIRED \
  102. __einfo_uniqify ( EINFO_EACCES, 0x09, "OCSP check required" )
  103. #define EACCES_WRONG_NAME \
  104. __einfo_error ( EINFO_EACCES_WRONG_NAME )
  105. #define EINFO_EACCES_WRONG_NAME \
  106. __einfo_uniqify ( EINFO_EACCES, 0x0a, "Incorrect certificate name" )
  107. #define EACCES_USELESS \
  108. __einfo_error ( EINFO_EACCES_USELESS )
  109. #define EINFO_EACCES_USELESS \
  110. __einfo_uniqify ( EINFO_EACCES, 0x0b, "No usable certificates" )
  111. /**
  112. * Get X.509 certificate name (for debugging)
  113. *
  114. * @v cert X.509 certificate
  115. * @ret name Name (for debugging)
  116. */
  117. const char * x509_name ( struct x509_certificate *cert ) {
  118. struct asn1_cursor *common_name = &cert->subject.common_name;
  119. struct digest_algorithm *digest = &sha1_algorithm;
  120. static char buf[64];
  121. uint8_t fingerprint[ digest->digestsize ];
  122. size_t len;
  123. len = common_name->len;
  124. if ( len ) {
  125. /* Certificate has a commonName: use that */
  126. if ( len > ( sizeof ( buf ) - 1 /* NUL */ ) )
  127. len = ( sizeof ( buf ) - 1 /* NUL */ );
  128. memcpy ( buf, common_name->data, len );
  129. buf[len] = '\0';
  130. } else {
  131. /* Certificate has no commonName: use SHA-1 fingerprint */
  132. x509_fingerprint ( cert, digest, fingerprint );
  133. base16_encode ( fingerprint, sizeof ( fingerprint ), buf );
  134. }
  135. return buf;
  136. }
  137. /** "commonName" object identifier */
  138. static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
  139. /** "commonName" object identifier cursor */
  140. static struct asn1_cursor oid_common_name_cursor =
  141. ASN1_OID_CURSOR ( oid_common_name );
  142. /**
  143. * Parse X.509 certificate version
  144. *
  145. * @v cert X.509 certificate
  146. * @v raw ASN.1 cursor
  147. * @ret rc Return status code
  148. */
  149. static int x509_parse_version ( struct x509_certificate *cert,
  150. const struct asn1_cursor *raw ) {
  151. struct asn1_cursor cursor;
  152. int version;
  153. int rc;
  154. /* Enter version */
  155. memcpy ( &cursor, raw, sizeof ( cursor ) );
  156. asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
  157. /* Parse integer */
  158. if ( ( rc = asn1_integer ( &cursor, &version ) ) != 0 ) {
  159. DBGC ( cert, "X509 %p cannot parse version: %s\n",
  160. cert, strerror ( rc ) );
  161. DBGC_HDA ( cert, 0, raw->data, raw->len );
  162. return rc;
  163. }
  164. /* Sanity check */
  165. if ( version < 0 ) {
  166. DBGC ( cert, "X509 %p invalid version %d\n", cert, version );
  167. DBGC_HDA ( cert, 0, raw->data, raw->len );
  168. return -EINVAL_VERSION;
  169. }
  170. /* Record version */
  171. cert->version = version;
  172. DBGC2 ( cert, "X509 %p is a version %d certificate\n",
  173. cert, ( cert->version + 1 ) );
  174. return 0;
  175. }
  176. /**
  177. * Parse X.509 certificate serial number
  178. *
  179. * @v cert X.509 certificate
  180. * @v raw ASN.1 cursor
  181. * @ret rc Return status code
  182. */
  183. static int x509_parse_serial ( struct x509_certificate *cert,
  184. const struct asn1_cursor *raw ) {
  185. struct x509_serial *serial = &cert->serial;
  186. int rc;
  187. /* Record raw serial number */
  188. memcpy ( &serial->raw, raw, sizeof ( serial->raw ) );
  189. if ( ( rc = asn1_shrink ( &serial->raw, ASN1_INTEGER ) ) != 0 ) {
  190. DBGC ( cert, "X509 %p cannot shrink serialNumber: %s\n",
  191. cert, strerror ( rc ) );
  192. return rc;
  193. }
  194. DBGC2 ( cert, "X509 %p issuer is:\n", cert );
  195. DBGC2_HDA ( cert, 0, serial->raw.data, serial->raw.len );
  196. return 0;
  197. }
  198. /**
  199. * Parse X.509 certificate issuer
  200. *
  201. * @v cert X.509 certificate
  202. * @v raw ASN.1 cursor
  203. * @ret rc Return status code
  204. */
  205. static int x509_parse_issuer ( struct x509_certificate *cert,
  206. const struct asn1_cursor *raw ) {
  207. struct x509_issuer *issuer = &cert->issuer;
  208. int rc;
  209. /* Record raw issuer */
  210. memcpy ( &issuer->raw, raw, sizeof ( issuer->raw ) );
  211. if ( ( rc = asn1_shrink ( &issuer->raw, ASN1_SEQUENCE ) ) != 0 ) {
  212. DBGC ( cert, "X509 %p cannot shrink issuer: %s\n",
  213. cert, strerror ( rc ) );
  214. return rc;
  215. }
  216. DBGC2 ( cert, "X509 %p issuer is:\n", cert );
  217. DBGC2_HDA ( cert, 0, issuer->raw.data, issuer->raw.len );
  218. return 0;
  219. }
  220. /**
  221. * Parse X.509 certificate validity
  222. *
  223. * @v cert X.509 certificate
  224. * @v raw ASN.1 cursor
  225. * @ret rc Return status code
  226. */
  227. static int x509_parse_validity ( struct x509_certificate *cert,
  228. const struct asn1_cursor *raw ) {
  229. struct x509_validity *validity = &cert->validity;
  230. struct x509_time *not_before = &validity->not_before;
  231. struct x509_time *not_after = &validity->not_after;
  232. struct asn1_cursor cursor;
  233. int rc;
  234. /* Enter validity */
  235. memcpy ( &cursor, raw, sizeof ( cursor ) );
  236. asn1_enter ( &cursor, ASN1_SEQUENCE );
  237. /* Parse notBefore */
  238. if ( ( rc = asn1_generalized_time ( &cursor,
  239. &not_before->time ) ) != 0 ) {
  240. DBGC ( cert, "X509 %p cannot parse notBefore: %s\n",
  241. cert, strerror ( rc ) );
  242. return rc;
  243. }
  244. DBGC2 ( cert, "X509 %p valid from time %lld\n",
  245. cert, not_before->time );
  246. asn1_skip_any ( &cursor );
  247. /* Parse notAfter */
  248. if ( ( rc = asn1_generalized_time ( &cursor,
  249. &not_after->time ) ) != 0 ) {
  250. DBGC ( cert, "X509 %p cannot parse notAfter: %s\n",
  251. cert, strerror ( rc ) );
  252. return rc;
  253. }
  254. DBGC2 ( cert, "X509 %p valid until time %lld\n",
  255. cert, not_after->time );
  256. return 0;
  257. }
  258. /**
  259. * Parse X.509 certificate common name
  260. *
  261. * @v cert X.509 certificate
  262. * @v raw ASN.1 cursor
  263. * @ret rc Return status code
  264. */
  265. static int x509_parse_common_name ( struct x509_certificate *cert,
  266. const struct asn1_cursor *raw ) {
  267. struct asn1_cursor cursor;
  268. struct asn1_cursor oid_cursor;
  269. struct asn1_cursor name_cursor;
  270. int rc;
  271. /* Enter name */
  272. memcpy ( &cursor, raw, sizeof ( cursor ) );
  273. asn1_enter ( &cursor, ASN1_SEQUENCE );
  274. /* Scan through name list */
  275. for ( ; cursor.len ; asn1_skip_any ( &cursor ) ) {
  276. /* Check for "commonName" OID */
  277. memcpy ( &oid_cursor, &cursor, sizeof ( oid_cursor ) );
  278. asn1_enter ( &oid_cursor, ASN1_SET );
  279. asn1_enter ( &oid_cursor, ASN1_SEQUENCE );
  280. memcpy ( &name_cursor, &oid_cursor, sizeof ( name_cursor ) );
  281. asn1_enter ( &oid_cursor, ASN1_OID );
  282. if ( asn1_compare ( &oid_common_name_cursor, &oid_cursor ) != 0)
  283. continue;
  284. asn1_skip_any ( &name_cursor );
  285. if ( ( rc = asn1_enter_any ( &name_cursor ) ) != 0 ) {
  286. DBGC ( cert, "X509 %p cannot locate name:\n", cert );
  287. DBGC_HDA ( cert, 0, raw->data, raw->len );
  288. return rc;
  289. }
  290. /* Record common name */
  291. memcpy ( &cert->subject.common_name, &name_cursor,
  292. sizeof ( cert->subject.common_name ) );
  293. return 0;
  294. }
  295. /* Certificates may not have a commonName */
  296. DBGC2 ( cert, "X509 %p no commonName found:\n", cert );
  297. return 0;
  298. }
  299. /**
  300. * Parse X.509 certificate subject
  301. *
  302. * @v cert X.509 certificate
  303. * @v raw ASN.1 cursor
  304. * @ret rc Return status code
  305. */
  306. static int x509_parse_subject ( struct x509_certificate *cert,
  307. const struct asn1_cursor *raw ) {
  308. struct x509_subject *subject = &cert->subject;
  309. int rc;
  310. /* Record raw subject */
  311. memcpy ( &subject->raw, raw, sizeof ( subject->raw ) );
  312. asn1_shrink_any ( &subject->raw );
  313. DBGC2 ( cert, "X509 %p subject is:\n", cert );
  314. DBGC2_HDA ( cert, 0, subject->raw.data, subject->raw.len );
  315. /* Parse common name */
  316. if ( ( rc = x509_parse_common_name ( cert, raw ) ) != 0 )
  317. return rc;
  318. DBGC2 ( cert, "X509 %p common name is \"%s\":\n", cert,
  319. x509_name ( cert ) );
  320. return 0;
  321. }
  322. /**
  323. * Parse X.509 certificate public key information
  324. *
  325. * @v cert X.509 certificate
  326. * @v raw ASN.1 cursor
  327. * @ret rc Return status code
  328. */
  329. static int x509_parse_public_key ( struct x509_certificate *cert,
  330. const struct asn1_cursor *raw ) {
  331. struct x509_public_key *public_key = &cert->subject.public_key;
  332. struct asn1_algorithm **algorithm = &public_key->algorithm;
  333. struct asn1_bit_string *raw_bits = &public_key->raw_bits;
  334. struct asn1_cursor cursor;
  335. int rc;
  336. /* Record raw subjectPublicKeyInfo */
  337. memcpy ( &cursor, raw, sizeof ( cursor ) );
  338. asn1_shrink_any ( &cursor );
  339. memcpy ( &public_key->raw, &cursor, sizeof ( public_key->raw ) );
  340. DBGC2 ( cert, "X509 %p public key is:\n", cert );
  341. DBGC2_HDA ( cert, 0, public_key->raw.data, public_key->raw.len );
  342. /* Enter subjectPublicKeyInfo */
  343. asn1_enter ( &cursor, ASN1_SEQUENCE );
  344. /* Parse algorithm */
  345. if ( ( rc = asn1_pubkey_algorithm ( &cursor, algorithm ) ) != 0 ) {
  346. DBGC ( cert, "X509 %p could not parse public key algorithm: "
  347. "%s\n", cert, strerror ( rc ) );
  348. return rc;
  349. }
  350. DBGC2 ( cert, "X509 %p public key algorithm is %s\n",
  351. cert, (*algorithm)->name );
  352. asn1_skip_any ( &cursor );
  353. /* Parse bit string */
  354. if ( ( rc = asn1_bit_string ( &cursor, raw_bits ) ) != 0 ) {
  355. DBGC ( cert, "X509 %p could not parse public key bits: %s\n",
  356. cert, strerror ( rc ) );
  357. return rc;
  358. }
  359. return 0;
  360. }
  361. /**
  362. * Parse X.509 certificate basic constraints
  363. *
  364. * @v cert X.509 certificate
  365. * @v raw ASN.1 cursor
  366. * @ret rc Return status code
  367. */
  368. static int x509_parse_basic_constraints ( struct x509_certificate *cert,
  369. const struct asn1_cursor *raw ) {
  370. struct x509_basic_constraints *basic = &cert->extensions.basic;
  371. struct asn1_cursor cursor;
  372. int ca = 0;
  373. int path_len;
  374. int rc;
  375. /* Enter basicConstraints */
  376. memcpy ( &cursor, raw, sizeof ( cursor ) );
  377. asn1_enter ( &cursor, ASN1_SEQUENCE );
  378. /* Parse "cA", if present */
  379. if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
  380. ca = asn1_boolean ( &cursor );
  381. if ( ca < 0 ) {
  382. rc = ca;
  383. DBGC ( cert, "X509 %p cannot parse cA: %s\n",
  384. cert, strerror ( rc ) );
  385. DBGC_HDA ( cert, 0, raw->data, raw->len );
  386. return rc;
  387. }
  388. asn1_skip_any ( &cursor );
  389. }
  390. basic->ca = ca;
  391. DBGC2 ( cert, "X509 %p is %sa CA certificate\n",
  392. cert, ( basic->ca ? "" : "not " ) );
  393. /* Ignore everything else unless "cA" is true */
  394. if ( ! ca )
  395. return 0;
  396. /* Parse "pathLenConstraint", if present and applicable */
  397. basic->path_len = X509_PATH_LEN_UNLIMITED;
  398. if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
  399. if ( ( rc = asn1_integer ( &cursor, &path_len ) ) != 0 ) {
  400. DBGC ( cert, "X509 %p cannot parse pathLenConstraint: "
  401. "%s\n", cert, strerror ( rc ) );
  402. DBGC_HDA ( cert, 0, raw->data, raw->len );
  403. return rc;
  404. }
  405. if ( path_len < 0 ) {
  406. DBGC ( cert, "X509 %p invalid pathLenConstraint %d\n",
  407. cert, path_len );
  408. DBGC_HDA ( cert, 0, raw->data, raw->len );
  409. return -EINVAL;
  410. }
  411. basic->path_len = path_len;
  412. DBGC2 ( cert, "X509 %p path length constraint is %u\n",
  413. cert, basic->path_len );
  414. }
  415. return 0;
  416. }
  417. /**
  418. * Parse X.509 certificate key usage
  419. *
  420. * @v cert X.509 certificate
  421. * @v raw ASN.1 cursor
  422. * @ret rc Return status code
  423. */
  424. static int x509_parse_key_usage ( struct x509_certificate *cert,
  425. const struct asn1_cursor *raw ) {
  426. struct x509_key_usage *usage = &cert->extensions.usage;
  427. struct asn1_bit_string bit_string;
  428. const uint8_t *bytes;
  429. size_t len;
  430. unsigned int i;
  431. int rc;
  432. /* Mark extension as present */
  433. usage->present = 1;
  434. /* Parse bit string */
  435. if ( ( rc = asn1_bit_string ( raw, &bit_string ) ) != 0 ) {
  436. DBGC ( cert, "X509 %p could not parse key usage: %s\n",
  437. cert, strerror ( rc ) );
  438. return rc;
  439. }
  440. /* Parse key usage bits */
  441. bytes = bit_string.data;
  442. len = bit_string.len;
  443. if ( len > sizeof ( usage->bits ) )
  444. len = sizeof ( usage->bits );
  445. for ( i = 0 ; i < len ; i++ ) {
  446. usage->bits |= ( *(bytes++) << ( 8 * i ) );
  447. }
  448. DBGC2 ( cert, "X509 %p key usage is %08x\n", cert, usage->bits );
  449. return 0;
  450. }
  451. /** "id-kp-codeSigning" object identifier */
  452. static uint8_t oid_code_signing[] = { ASN1_OID_CODESIGNING };
  453. /** "id-kp-OCSPSigning" object identifier */
  454. static uint8_t oid_ocsp_signing[] = { ASN1_OID_OCSPSIGNING };
  455. /** Supported key purposes */
  456. static struct x509_key_purpose x509_key_purposes[] = {
  457. {
  458. .name = "codeSigning",
  459. .bits = X509_CODE_SIGNING,
  460. .oid = ASN1_OID_CURSOR ( oid_code_signing ),
  461. },
  462. {
  463. .name = "ocspSigning",
  464. .bits = X509_OCSP_SIGNING,
  465. .oid = ASN1_OID_CURSOR ( oid_ocsp_signing ),
  466. },
  467. };
  468. /**
  469. * Parse X.509 certificate key purpose identifier
  470. *
  471. * @v cert X.509 certificate
  472. * @v raw ASN.1 cursor
  473. * @ret rc Return status code
  474. */
  475. static int x509_parse_key_purpose ( struct x509_certificate *cert,
  476. const struct asn1_cursor *raw ) {
  477. struct x509_extended_key_usage *ext_usage = &cert->extensions.ext_usage;
  478. struct x509_key_purpose *purpose;
  479. struct asn1_cursor cursor;
  480. unsigned int i;
  481. int rc;
  482. /* Enter keyPurposeId */
  483. memcpy ( &cursor, raw, sizeof ( cursor ) );
  484. if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
  485. DBGC ( cert, "X509 %p invalid keyPurposeId:\n", cert );
  486. DBGC_HDA ( cert, 0, raw->data, raw->len );
  487. return rc;
  488. }
  489. /* Identify key purpose */
  490. for ( i = 0 ; i < ( sizeof ( x509_key_purposes ) /
  491. sizeof ( x509_key_purposes[0] ) ) ; i++ ) {
  492. purpose = &x509_key_purposes[i];
  493. if ( asn1_compare ( &cursor, &purpose->oid ) == 0 ) {
  494. DBGC2 ( cert, "X509 %p has key purpose %s\n",
  495. cert, purpose->name );
  496. ext_usage->bits |= purpose->bits;
  497. return 0;
  498. }
  499. }
  500. /* Ignore unrecognised key purposes */
  501. return 0;
  502. }
  503. /**
  504. * Parse X.509 certificate extended key usage
  505. *
  506. * @v cert X.509 certificate
  507. * @v raw ASN.1 cursor
  508. * @ret rc Return status code
  509. */
  510. static int x509_parse_extended_key_usage ( struct x509_certificate *cert,
  511. const struct asn1_cursor *raw ) {
  512. struct asn1_cursor cursor;
  513. int rc;
  514. /* Enter extKeyUsage */
  515. memcpy ( &cursor, raw, sizeof ( cursor ) );
  516. asn1_enter ( &cursor, ASN1_SEQUENCE );
  517. /* Parse each extended key usage in turn */
  518. while ( cursor.len ) {
  519. if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
  520. return rc;
  521. asn1_skip_any ( &cursor );
  522. }
  523. return 0;
  524. }
  525. /**
  526. * Parse X.509 certificate OCSP access method
  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_ocsp ( struct x509_certificate *cert,
  533. const struct asn1_cursor *raw ) {
  534. struct x509_ocsp_responder *ocsp = &cert->extensions.auth_info.ocsp;
  535. struct asn1_cursor *uri = &ocsp->uri;
  536. int rc;
  537. /* Enter accessLocation */
  538. memcpy ( uri, raw, sizeof ( *uri ) );
  539. if ( ( rc = asn1_enter ( uri, ASN1_IMPLICIT_TAG ( 6 ) ) ) != 0 ) {
  540. DBGC ( cert, "X509 %p OCSP does not contain "
  541. "uniformResourceIdentifier:\n", cert );
  542. DBGC_HDA ( cert, 0, raw->data, raw->len );
  543. return rc;
  544. }
  545. DBGC2 ( cert, "X509 %p OCSP URI is:\n", cert );
  546. DBGC2_HDA ( cert, 0, uri->data, uri->len );
  547. return 0;
  548. }
  549. /** "id-ad-ocsp" object identifier */
  550. static uint8_t oid_ad_ocsp[] = { ASN1_OID_OCSP };
  551. /** Supported access methods */
  552. static struct x509_access_method x509_access_methods[] = {
  553. {
  554. .name = "OCSP",
  555. .oid = ASN1_OID_CURSOR ( oid_ad_ocsp ),
  556. .parse = x509_parse_ocsp,
  557. },
  558. };
  559. /**
  560. * Identify X.509 access method by OID
  561. *
  562. * @v oid OID
  563. * @ret method Access method, or NULL
  564. */
  565. static struct x509_access_method *
  566. x509_find_access_method ( const struct asn1_cursor *oid ) {
  567. struct x509_access_method *method;
  568. unsigned int i;
  569. for ( i = 0 ; i < ( sizeof ( x509_access_methods ) /
  570. sizeof ( x509_access_methods[0] ) ) ; i++ ) {
  571. method = &x509_access_methods[i];
  572. if ( asn1_compare ( &method->oid, oid ) == 0 )
  573. return method;
  574. }
  575. return NULL;
  576. }
  577. /**
  578. * Parse X.509 certificate access description
  579. *
  580. * @v cert X.509 certificate
  581. * @v raw ASN.1 cursor
  582. * @ret rc Return status code
  583. */
  584. static int x509_parse_access_description ( struct x509_certificate *cert,
  585. const struct asn1_cursor *raw ) {
  586. struct asn1_cursor cursor;
  587. struct asn1_cursor subcursor;
  588. struct x509_access_method *method;
  589. int rc;
  590. /* Enter keyPurposeId */
  591. memcpy ( &cursor, raw, sizeof ( cursor ) );
  592. asn1_enter ( &cursor, ASN1_SEQUENCE );
  593. /* Try to identify access method */
  594. memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
  595. asn1_enter ( &subcursor, ASN1_OID );
  596. method = x509_find_access_method ( &subcursor );
  597. asn1_skip_any ( &cursor );
  598. DBGC2 ( cert, "X509 %p found access method %s\n",
  599. cert, ( method ? method->name : "<unknown>" ) );
  600. /* Parse access location, if applicable */
  601. if ( method && ( ( rc = method->parse ( cert, &cursor ) ) != 0 ) )
  602. return rc;
  603. return 0;
  604. }
  605. /**
  606. * Parse X.509 certificate authority information access
  607. *
  608. * @v cert X.509 certificate
  609. * @v raw ASN.1 cursor
  610. * @ret rc Return status code
  611. */
  612. static int x509_parse_authority_info_access ( struct x509_certificate *cert,
  613. const struct asn1_cursor *raw ) {
  614. struct asn1_cursor cursor;
  615. int rc;
  616. /* Enter authorityInfoAccess */
  617. memcpy ( &cursor, raw, sizeof ( cursor ) );
  618. asn1_enter ( &cursor, ASN1_SEQUENCE );
  619. /* Parse each access description in turn */
  620. while ( cursor.len ) {
  621. if ( ( rc = x509_parse_access_description ( cert,
  622. &cursor ) ) != 0 )
  623. return rc;
  624. asn1_skip_any ( &cursor );
  625. }
  626. return 0;
  627. }
  628. /** "id-ce-basicConstraints" object identifier */
  629. static uint8_t oid_ce_basic_constraints[] =
  630. { ASN1_OID_BASICCONSTRAINTS };
  631. /** "id-ce-keyUsage" object identifier */
  632. static uint8_t oid_ce_key_usage[] =
  633. { ASN1_OID_KEYUSAGE };
  634. /** "id-ce-extKeyUsage" object identifier */
  635. static uint8_t oid_ce_ext_key_usage[] =
  636. { ASN1_OID_EXTKEYUSAGE };
  637. /** "id-pe-authorityInfoAccess" object identifier */
  638. static uint8_t oid_pe_authority_info_access[] =
  639. { ASN1_OID_AUTHORITYINFOACCESS };
  640. /** Supported certificate extensions */
  641. static struct x509_extension x509_extensions[] = {
  642. {
  643. .name = "basicConstraints",
  644. .oid = ASN1_OID_CURSOR ( oid_ce_basic_constraints ),
  645. .parse = x509_parse_basic_constraints,
  646. },
  647. {
  648. .name = "keyUsage",
  649. .oid = ASN1_OID_CURSOR ( oid_ce_key_usage ),
  650. .parse = x509_parse_key_usage,
  651. },
  652. {
  653. .name = "extKeyUsage",
  654. .oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
  655. .parse = x509_parse_extended_key_usage,
  656. },
  657. {
  658. .name = "authorityInfoAccess",
  659. .oid = ASN1_OID_CURSOR ( oid_pe_authority_info_access ),
  660. .parse = x509_parse_authority_info_access,
  661. },
  662. };
  663. /**
  664. * Identify X.509 extension by OID
  665. *
  666. * @v oid OID
  667. * @ret extension Extension, or NULL
  668. */
  669. static struct x509_extension *
  670. x509_find_extension ( const struct asn1_cursor *oid ) {
  671. struct x509_extension *extension;
  672. unsigned int i;
  673. for ( i = 0 ; i < ( sizeof ( x509_extensions ) /
  674. sizeof ( x509_extensions[0] ) ) ; i++ ) {
  675. extension = &x509_extensions[i];
  676. if ( asn1_compare ( &extension->oid, oid ) == 0 )
  677. return extension;
  678. }
  679. return NULL;
  680. }
  681. /**
  682. * Parse X.509 certificate extension
  683. *
  684. * @v cert X.509 certificate
  685. * @v raw ASN.1 cursor
  686. * @ret rc Return status code
  687. */
  688. static int x509_parse_extension ( struct x509_certificate *cert,
  689. const struct asn1_cursor *raw ) {
  690. struct asn1_cursor cursor;
  691. struct asn1_cursor subcursor;
  692. struct x509_extension *extension;
  693. int is_critical = 0;
  694. int rc;
  695. /* Enter extension */
  696. memcpy ( &cursor, raw, sizeof ( cursor ) );
  697. asn1_enter ( &cursor, ASN1_SEQUENCE );
  698. /* Try to identify extension */
  699. memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
  700. asn1_enter ( &subcursor, ASN1_OID );
  701. extension = x509_find_extension ( &subcursor );
  702. asn1_skip_any ( &cursor );
  703. DBGC2 ( cert, "X509 %p found extension %s\n",
  704. cert, ( extension ? extension->name : "<unknown>" ) );
  705. /* Identify criticality */
  706. if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
  707. is_critical = asn1_boolean ( &cursor );
  708. if ( is_critical < 0 ) {
  709. rc = is_critical;
  710. DBGC ( cert, "X509 %p cannot parse extension "
  711. "criticality: %s\n", cert, strerror ( rc ) );
  712. DBGC_HDA ( cert, 0, raw->data, raw->len );
  713. return rc;
  714. }
  715. asn1_skip_any ( &cursor );
  716. }
  717. /* Handle unknown extensions */
  718. if ( ! extension ) {
  719. if ( is_critical ) {
  720. /* Fail if we cannot handle a critical extension */
  721. DBGC ( cert, "X509 %p cannot handle critical "
  722. "extension:\n", cert );
  723. DBGC_HDA ( cert, 0, raw->data, raw->len );
  724. return -ENOTSUP_EXTENSION;
  725. } else {
  726. /* Ignore unknown non-critical extensions */
  727. return 0;
  728. }
  729. };
  730. /* Extract extnValue */
  731. if ( ( rc = asn1_enter ( &cursor, ASN1_OCTET_STRING ) ) != 0 ) {
  732. DBGC ( cert, "X509 %p extension missing extnValue:\n", cert );
  733. DBGC_HDA ( cert, 0, raw->data, raw->len );
  734. return rc;
  735. }
  736. /* Parse extension */
  737. if ( ( rc = extension->parse ( cert, &cursor ) ) != 0 )
  738. return rc;
  739. return 0;
  740. }
  741. /**
  742. * Parse X.509 certificate extensions, if present
  743. *
  744. * @v cert X.509 certificate
  745. * @v raw ASN.1 cursor
  746. * @ret rc Return status code
  747. */
  748. static int x509_parse_extensions ( struct x509_certificate *cert,
  749. const struct asn1_cursor *raw ) {
  750. struct asn1_cursor cursor;
  751. int rc;
  752. /* Enter extensions, if present */
  753. memcpy ( &cursor, raw, sizeof ( cursor ) );
  754. asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 3 ) );
  755. asn1_enter ( &cursor, ASN1_SEQUENCE );
  756. /* Parse each extension in turn */
  757. while ( cursor.len ) {
  758. if ( ( rc = x509_parse_extension ( cert, &cursor ) ) != 0 )
  759. return rc;
  760. asn1_skip_any ( &cursor );
  761. }
  762. return 0;
  763. }
  764. /**
  765. * Parse X.509 certificate tbsCertificate
  766. *
  767. * @v cert X.509 certificate
  768. * @v raw ASN.1 cursor
  769. * @ret rc Return status code
  770. */
  771. static int x509_parse_tbscertificate ( struct x509_certificate *cert,
  772. const struct asn1_cursor *raw ) {
  773. struct asn1_algorithm **algorithm = &cert->signature_algorithm;
  774. struct asn1_cursor cursor;
  775. int rc;
  776. /* Record raw tbsCertificate */
  777. memcpy ( &cursor, raw, sizeof ( cursor ) );
  778. asn1_shrink_any ( &cursor );
  779. memcpy ( &cert->tbs, &cursor, sizeof ( cert->tbs ) );
  780. /* Enter tbsCertificate */
  781. asn1_enter ( &cursor, ASN1_SEQUENCE );
  782. /* Parse version, if present */
  783. if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
  784. if ( ( rc = x509_parse_version ( cert, &cursor ) ) != 0 )
  785. return rc;
  786. asn1_skip_any ( &cursor );
  787. }
  788. /* Parse serialNumber */
  789. if ( ( rc = x509_parse_serial ( cert, &cursor ) ) != 0 )
  790. return rc;
  791. asn1_skip_any ( &cursor );
  792. /* Parse signature */
  793. if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
  794. DBGC ( cert, "X509 %p could not parse signature algorithm: "
  795. "%s\n", cert, strerror ( rc ) );
  796. return rc;
  797. }
  798. DBGC2 ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
  799. cert, (*algorithm)->name );
  800. asn1_skip_any ( &cursor );
  801. /* Parse issuer */
  802. if ( ( rc = x509_parse_issuer ( cert, &cursor ) ) != 0 )
  803. return rc;
  804. asn1_skip_any ( &cursor );
  805. /* Parse validity */
  806. if ( ( rc = x509_parse_validity ( cert, &cursor ) ) != 0 )
  807. return rc;
  808. asn1_skip_any ( &cursor );
  809. /* Parse subject */
  810. if ( ( rc = x509_parse_subject ( cert, &cursor ) ) != 0 )
  811. return rc;
  812. asn1_skip_any ( &cursor );
  813. /* Parse subjectPublicKeyInfo */
  814. if ( ( rc = x509_parse_public_key ( cert, &cursor ) ) != 0 )
  815. return rc;
  816. asn1_skip_any ( &cursor );
  817. /* Parse extensions, if present */
  818. if ( ( rc = x509_parse_extensions ( cert, &cursor ) ) != 0 )
  819. return rc;
  820. return 0;
  821. }
  822. /**
  823. * Parse X.509 certificate from ASN.1 data
  824. *
  825. * @v cert X.509 certificate
  826. * @v raw ASN.1 cursor
  827. * @ret rc Return status code
  828. */
  829. int x509_parse ( struct x509_certificate *cert,
  830. const struct asn1_cursor *raw ) {
  831. struct x509_signature *signature = &cert->signature;
  832. struct asn1_algorithm **signature_algorithm = &signature->algorithm;
  833. struct asn1_bit_string *signature_value = &signature->value;
  834. struct asn1_cursor cursor;
  835. int rc;
  836. /* Record raw certificate */
  837. memcpy ( &cursor, raw, sizeof ( cursor ) );
  838. memcpy ( &cert->raw, &cursor, sizeof ( cert->raw ) );
  839. /* Enter certificate */
  840. asn1_enter ( &cursor, ASN1_SEQUENCE );
  841. /* Parse tbsCertificate */
  842. if ( ( rc = x509_parse_tbscertificate ( cert, &cursor ) ) != 0 )
  843. return rc;
  844. asn1_skip_any ( &cursor );
  845. /* Parse signatureAlgorithm */
  846. if ( ( rc = asn1_signature_algorithm ( &cursor,
  847. signature_algorithm ) ) != 0 ) {
  848. DBGC ( cert, "X509 %p could not parse signature algorithm: "
  849. "%s\n", cert, strerror ( rc ) );
  850. return rc;
  851. }
  852. DBGC2 ( cert, "X509 %p signatureAlgorithm is %s\n",
  853. cert, (*signature_algorithm)->name );
  854. asn1_skip_any ( &cursor );
  855. /* Parse signatureValue */
  856. if ( ( rc = asn1_integral_bit_string ( &cursor,
  857. signature_value ) ) != 0 ) {
  858. DBGC ( cert, "X509 %p could not parse signature value: %s\n",
  859. cert, strerror ( rc ) );
  860. return rc;
  861. }
  862. DBGC2 ( cert, "X509 %p signatureValue is:\n", cert );
  863. DBGC2_HDA ( cert, 0, signature_value->data, signature_value->len );
  864. /* Check that algorithm in tbsCertificate matches algorithm in
  865. * signature
  866. */
  867. if ( signature->algorithm != (*signature_algorithm) ) {
  868. DBGC ( cert, "X509 %p signature algorithm %s does not match "
  869. "signatureAlgorithm %s\n",
  870. cert, signature->algorithm->name,
  871. (*signature_algorithm)->name );
  872. return -EINVAL_ALGORITHM_MISMATCH;
  873. }
  874. return 0;
  875. }
  876. /**
  877. * Create X.509 certificate
  878. *
  879. * @v data Raw certificate data
  880. * @v len Length of raw data
  881. * @ret cert X.509 certificate
  882. * @ret rc Return status code
  883. *
  884. * On success, the caller holds a reference to the X.509 certificate,
  885. * and is responsible for ultimately calling x509_put().
  886. */
  887. int x509_certificate ( const void *data, size_t len,
  888. struct x509_certificate **cert ) {
  889. struct asn1_cursor cursor;
  890. void *raw;
  891. int rc;
  892. /* Initialise cursor */
  893. cursor.data = data;
  894. cursor.len = len;
  895. asn1_shrink_any ( &cursor );
  896. /* Return stored certificate, if present */
  897. if ( ( *cert = certstore_find ( &cursor ) ) != NULL ) {
  898. /* Add caller's reference */
  899. x509_get ( *cert );
  900. return 0;
  901. }
  902. /* Allocate and initialise certificate */
  903. *cert = zalloc ( sizeof ( **cert ) + cursor.len );
  904. if ( ! *cert )
  905. return -ENOMEM;
  906. ref_init ( &(*cert)->refcnt, NULL );
  907. raw = ( *cert + 1 );
  908. /* Copy raw data */
  909. memcpy ( raw, cursor.data, cursor.len );
  910. cursor.data = raw;
  911. /* Parse certificate */
  912. if ( ( rc = x509_parse ( *cert, &cursor ) ) != 0 ) {
  913. x509_put ( *cert );
  914. *cert = NULL;
  915. return rc;
  916. }
  917. /* Add certificate to store */
  918. certstore_add ( *cert );
  919. return 0;
  920. }
  921. /**
  922. * Check X.509 certificate signature
  923. *
  924. * @v cert X.509 certificate
  925. * @v public_key X.509 public key
  926. * @ret rc Return status code
  927. */
  928. static int x509_check_signature ( struct x509_certificate *cert,
  929. struct x509_public_key *public_key ) {
  930. struct x509_signature *signature = &cert->signature;
  931. struct asn1_algorithm *algorithm = signature->algorithm;
  932. struct digest_algorithm *digest = algorithm->digest;
  933. struct pubkey_algorithm *pubkey = algorithm->pubkey;
  934. uint8_t digest_ctx[ digest->ctxsize ];
  935. uint8_t digest_out[ digest->digestsize ];
  936. uint8_t pubkey_ctx[ pubkey->ctxsize ];
  937. int rc;
  938. /* Sanity check */
  939. assert ( cert->signature_algorithm == cert->signature.algorithm );
  940. /* Calculate certificate digest */
  941. digest_init ( digest, digest_ctx );
  942. digest_update ( digest, digest_ctx, cert->tbs.data, cert->tbs.len );
  943. digest_final ( digest, digest_ctx, digest_out );
  944. DBGC2 ( cert, "X509 %p \"%s\" digest:\n", cert, x509_name ( cert ) );
  945. DBGC2_HDA ( cert, 0, digest_out, sizeof ( digest_out ) );
  946. /* Check that signature public key algorithm matches signer */
  947. if ( public_key->algorithm->pubkey != pubkey ) {
  948. DBGC ( cert, "X509 %p \"%s\" signature algorithm %s does not "
  949. "match signer's algorithm %s\n",
  950. cert, x509_name ( cert ), algorithm->name,
  951. public_key->algorithm->name );
  952. rc = -EINVAL_ALGORITHM_MISMATCH;
  953. goto err_mismatch;
  954. }
  955. /* Verify signature using signer's public key */
  956. if ( ( rc = pubkey_init ( pubkey, pubkey_ctx, public_key->raw.data,
  957. public_key->raw.len ) ) != 0 ) {
  958. DBGC ( cert, "X509 %p \"%s\" cannot initialise public key: "
  959. "%s\n", cert, x509_name ( cert ), strerror ( rc ) );
  960. goto err_pubkey_init;
  961. }
  962. if ( ( rc = pubkey_verify ( pubkey, pubkey_ctx, digest, digest_out,
  963. signature->value.data,
  964. signature->value.len ) ) != 0 ) {
  965. DBGC ( cert, "X509 %p \"%s\" signature verification failed: "
  966. "%s\n", cert, x509_name ( cert ), strerror ( rc ) );
  967. goto err_pubkey_verify;
  968. }
  969. /* Success */
  970. rc = 0;
  971. err_pubkey_verify:
  972. pubkey_final ( pubkey, pubkey_ctx );
  973. err_pubkey_init:
  974. err_mismatch:
  975. return rc;
  976. }
  977. /**
  978. * Check X.509 certificate against issuer certificate
  979. *
  980. * @v cert X.509 certificate
  981. * @v issuer X.509 issuer certificate
  982. * @ret rc Return status code
  983. */
  984. int x509_check_issuer ( struct x509_certificate *cert,
  985. struct x509_certificate *issuer ) {
  986. struct x509_public_key *public_key = &issuer->subject.public_key;
  987. int rc;
  988. /* Check issuer. In theory, this should be a full X.500 DN
  989. * comparison, which would require support for a plethora of
  990. * abominations such as TeletexString (which allows the
  991. * character set to be changed mid-string using escape codes).
  992. * In practice, we assume that anyone who deliberately changes
  993. * the encoding of the issuer DN is probably a masochist who
  994. * will rather enjoy the process of figuring out exactly why
  995. * their certificate doesn't work.
  996. *
  997. * See http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
  998. * for some enjoyable ranting on this subject.
  999. */
  1000. if ( asn1_compare ( &cert->issuer.raw, &issuer->subject.raw ) != 0 ) {
  1001. DBGC ( cert, "X509 %p \"%s\" issuer does not match ",
  1002. cert, x509_name ( cert ) );
  1003. DBGC ( cert, "X509 %p \"%s\" subject\n",
  1004. issuer, x509_name ( issuer ) );
  1005. DBGC_HDA ( cert, 0, cert->issuer.raw.data,
  1006. cert->issuer.raw.len );
  1007. DBGC_HDA ( issuer, 0, issuer->subject.raw.data,
  1008. issuer->subject.raw.len );
  1009. return -EACCES_WRONG_ISSUER;
  1010. }
  1011. /* Check that issuer is allowed to sign certificates */
  1012. if ( ! issuer->extensions.basic.ca ) {
  1013. DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
  1014. issuer, x509_name ( issuer ) );
  1015. DBGC ( issuer, "X509 %p \"%s\": not a CA certificate\n",
  1016. cert, x509_name ( cert ) );
  1017. return -EACCES_NOT_CA;
  1018. }
  1019. if ( issuer->extensions.usage.present &&
  1020. ( ! ( issuer->extensions.usage.bits & X509_KEY_CERT_SIGN ) ) ) {
  1021. DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
  1022. issuer, x509_name ( issuer ) );
  1023. DBGC ( issuer, "X509 %p \"%s\": no keyCertSign usage\n",
  1024. cert, x509_name ( cert ) );
  1025. return -EACCES_KEY_USAGE;
  1026. }
  1027. /* Check signature */
  1028. if ( ( rc = x509_check_signature ( cert, public_key ) ) != 0 )
  1029. return rc;
  1030. return 0;
  1031. }
  1032. /**
  1033. * Calculate X.509 certificate fingerprint
  1034. *
  1035. * @v cert X.509 certificate
  1036. * @v digest Digest algorithm
  1037. * @v fingerprint Fingerprint buffer
  1038. */
  1039. void x509_fingerprint ( struct x509_certificate *cert,
  1040. struct digest_algorithm *digest,
  1041. void *fingerprint ) {
  1042. uint8_t ctx[ digest->ctxsize ];
  1043. /* Calculate fingerprint */
  1044. digest_init ( digest, ctx );
  1045. digest_update ( digest, ctx, cert->raw.data, cert->raw.len );
  1046. digest_final ( digest, ctx, fingerprint );
  1047. }
  1048. /**
  1049. * Check X.509 root certificate
  1050. *
  1051. * @v cert X.509 certificate
  1052. * @v root X.509 root certificate list
  1053. * @ret rc Return status code
  1054. */
  1055. int x509_check_root ( struct x509_certificate *cert, struct x509_root *root ) {
  1056. struct digest_algorithm *digest = root->digest;
  1057. uint8_t fingerprint[ digest->digestsize ];
  1058. const uint8_t *root_fingerprint = root->fingerprints;
  1059. unsigned int i;
  1060. /* Calculate certificate fingerprint */
  1061. x509_fingerprint ( cert, digest, fingerprint );
  1062. /* Check fingerprint against all root certificates */
  1063. for ( i = 0 ; i < root->count ; i++ ) {
  1064. if ( memcmp ( fingerprint, root_fingerprint,
  1065. sizeof ( fingerprint ) ) == 0 ) {
  1066. DBGC ( cert, "X509 %p \"%s\" is a root certificate\n",
  1067. cert, x509_name ( cert ) );
  1068. return 0;
  1069. }
  1070. root_fingerprint += sizeof ( fingerprint );
  1071. }
  1072. DBGC2 ( cert, "X509 %p \"%s\" is not a root certificate\n",
  1073. cert, x509_name ( cert ) );
  1074. return -ENOENT;
  1075. }
  1076. /**
  1077. * Check X.509 certificate validity period
  1078. *
  1079. * @v cert X.509 certificate
  1080. * @v time Time at which to check certificate
  1081. * @ret rc Return status code
  1082. */
  1083. int x509_check_time ( struct x509_certificate *cert, time_t time ) {
  1084. struct x509_validity *validity = &cert->validity;
  1085. /* Check validity period */
  1086. if ( validity->not_before.time > ( time + X509_ERROR_MARGIN_TIME ) ) {
  1087. DBGC ( cert, "X509 %p \"%s\" is not yet valid (at time %lld)\n",
  1088. cert, x509_name ( cert ), time );
  1089. return -EACCES_EXPIRED;
  1090. }
  1091. if ( validity->not_after.time < ( time - X509_ERROR_MARGIN_TIME ) ) {
  1092. DBGC ( cert, "X509 %p \"%s\" has expired (at time %lld)\n",
  1093. cert, x509_name ( cert ), time );
  1094. return -EACCES_EXPIRED;
  1095. }
  1096. DBGC2 ( cert, "X509 %p \"%s\" is valid (at time %lld)\n",
  1097. cert, x509_name ( cert ), time );
  1098. return 0;
  1099. }
  1100. /**
  1101. * Validate X.509 certificate
  1102. *
  1103. * @v cert X.509 certificate
  1104. * @v issuer Issuing X.509 certificate (or NULL)
  1105. * @v time Time at which to validate certificate
  1106. * @v root Root certificate list, or NULL to use default
  1107. * @ret rc Return status code
  1108. *
  1109. * The issuing certificate must have already been validated.
  1110. *
  1111. * Validation results are cached: if a certificate has already been
  1112. * successfully validated then @c issuer, @c time, and @c root will be
  1113. * ignored.
  1114. */
  1115. int x509_validate ( struct x509_certificate *cert,
  1116. struct x509_certificate *issuer,
  1117. time_t time, struct x509_root *root ) {
  1118. unsigned int max_path_remaining;
  1119. int rc;
  1120. /* Use default root certificate store if none specified */
  1121. if ( ! root )
  1122. root = &root_certificates;
  1123. /* Return success if certificate has already been validated */
  1124. if ( cert->valid )
  1125. return 0;
  1126. /* Fail if certificate is invalid at specified time */
  1127. if ( ( rc = x509_check_time ( cert, time ) ) != 0 )
  1128. return rc;
  1129. /* Succeed if certificate is a trusted root certificate */
  1130. if ( x509_check_root ( cert, root ) == 0 ) {
  1131. cert->valid = 1;
  1132. cert->path_remaining = ( cert->extensions.basic.path_len + 1 );
  1133. return 0;
  1134. }
  1135. /* Fail unless we have an issuer */
  1136. if ( ! issuer ) {
  1137. DBGC2 ( cert, "X509 %p \"%s\" has no issuer\n",
  1138. cert, x509_name ( cert ) );
  1139. return -EACCES_UNTRUSTED;
  1140. }
  1141. /* Fail unless issuer has already been validated */
  1142. if ( ! issuer->valid ) {
  1143. DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
  1144. DBGC ( cert, "issuer %p \"%s\" has not yet been validated\n",
  1145. issuer, x509_name ( issuer ) );
  1146. return -EACCES_OUT_OF_ORDER;
  1147. }
  1148. /* Fail if issuing certificate cannot validate this certificate */
  1149. if ( ( rc = x509_check_issuer ( cert, issuer ) ) != 0 )
  1150. return rc;
  1151. /* Fail if path length constraint is violated */
  1152. if ( issuer->path_remaining == 0 ) {
  1153. DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
  1154. DBGC ( cert, "issuer %p \"%s\" path length exceeded\n",
  1155. issuer, x509_name ( issuer ) );
  1156. return -EACCES_PATH_LEN;
  1157. }
  1158. /* Fail if OCSP is required */
  1159. if ( cert->extensions.auth_info.ocsp.uri.len &&
  1160. ( ! cert->extensions.auth_info.ocsp.good ) ) {
  1161. DBGC ( cert, "X509 %p \"%s\" requires an OCSP check\n",
  1162. cert, x509_name ( cert ) );
  1163. return -EACCES_OCSP_REQUIRED;
  1164. }
  1165. /* Calculate effective path length */
  1166. cert->path_remaining = ( issuer->path_remaining - 1 );
  1167. max_path_remaining = ( cert->extensions.basic.path_len + 1 );
  1168. if ( cert->path_remaining > max_path_remaining )
  1169. cert->path_remaining = max_path_remaining;
  1170. /* Mark certificate as valid */
  1171. cert->valid = 1;
  1172. DBGC ( cert, "X509 %p \"%s\" successfully validated using ",
  1173. cert, x509_name ( cert ) );
  1174. DBGC ( cert, "issuer %p \"%s\"\n", issuer, x509_name ( issuer ) );
  1175. return 0;
  1176. }
  1177. /**
  1178. * Check X.509 certificate name
  1179. *
  1180. * @v cert X.509 certificate
  1181. * @v name Name
  1182. * @ret rc Return status code
  1183. */
  1184. int x509_check_name ( struct x509_certificate *cert, const char *name ) {
  1185. struct asn1_cursor *common_name = &cert->subject.common_name;
  1186. size_t len = strlen ( name );
  1187. /* Check commonName */
  1188. if ( ! ( ( len == common_name->len ) &&
  1189. ( memcmp ( name, common_name->data, len ) == 0 ) ) ) {
  1190. DBGC ( cert, "X509 %p \"%s\" does not match name \"%s\"\n",
  1191. cert, x509_name ( cert ), name );
  1192. return -EACCES_WRONG_NAME;
  1193. }
  1194. return 0;
  1195. }
  1196. /**
  1197. * Free X.509 certificate chain
  1198. *
  1199. * @v refcnt Reference count
  1200. */
  1201. static void x509_free_chain ( struct refcnt *refcnt ) {
  1202. struct x509_chain *chain =
  1203. container_of ( refcnt, struct x509_chain, refcnt );
  1204. struct x509_link *link;
  1205. struct x509_link *tmp;
  1206. DBGC2 ( chain, "X509 chain %p freed\n", chain );
  1207. /* Free each link in the chain */
  1208. list_for_each_entry_safe ( link, tmp, &chain->links, list ) {
  1209. x509_put ( link->cert );
  1210. list_del ( &link->list );
  1211. free ( link );
  1212. }
  1213. /* Free chain */
  1214. free ( chain );
  1215. }
  1216. /**
  1217. * Allocate X.509 certificate chain
  1218. *
  1219. * @ret chain X.509 certificate chain, or NULL
  1220. */
  1221. struct x509_chain * x509_alloc_chain ( void ) {
  1222. struct x509_chain *chain;
  1223. /* Allocate chain */
  1224. chain = zalloc ( sizeof ( *chain ) );
  1225. if ( ! chain )
  1226. return NULL;
  1227. /* Initialise chain */
  1228. ref_init ( &chain->refcnt, x509_free_chain );
  1229. INIT_LIST_HEAD ( &chain->links );
  1230. DBGC2 ( chain, "X509 chain %p allocated\n", chain );
  1231. return chain;
  1232. }
  1233. /**
  1234. * Append X.509 certificate to X.509 certificate chain
  1235. *
  1236. * @v chain X.509 certificate chain
  1237. * @v cert X.509 certificate
  1238. * @ret rc Return status code
  1239. */
  1240. int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ) {
  1241. struct x509_link *link;
  1242. /* Allocate link */
  1243. link = zalloc ( sizeof ( *link ) );
  1244. if ( ! link )
  1245. return -ENOMEM;
  1246. /* Add link to chain */
  1247. link->cert = x509_get ( cert );
  1248. list_add_tail ( &link->list, &chain->links );
  1249. DBGC ( chain, "X509 chain %p added X509 %p \"%s\"\n",
  1250. chain, cert, x509_name ( cert ) );
  1251. return 0;
  1252. }
  1253. /**
  1254. * Append X.509 certificate to X.509 certificate chain
  1255. *
  1256. * @v chain X.509 certificate chain
  1257. * @v data Raw certificate data
  1258. * @v len Length of raw data
  1259. * @ret rc Return status code
  1260. */
  1261. int x509_append_raw ( struct x509_chain *chain, const void *data,
  1262. size_t len ) {
  1263. struct x509_certificate *cert;
  1264. int rc;
  1265. /* Parse certificate */
  1266. if ( ( rc = x509_certificate ( data, len, &cert ) ) != 0 )
  1267. goto err_parse;
  1268. /* Append certificate to chain */
  1269. if ( ( rc = x509_append ( chain, cert ) ) != 0 )
  1270. goto err_append;
  1271. /* Drop reference to certificate */
  1272. x509_put ( cert );
  1273. return 0;
  1274. err_append:
  1275. x509_put ( cert );
  1276. err_parse:
  1277. return rc;
  1278. }
  1279. /**
  1280. * Identify X.509 certificate by subject
  1281. *
  1282. * @v certs X.509 certificate list
  1283. * @v subject Subject
  1284. * @ret cert X.509 certificate, or NULL if not found
  1285. */
  1286. static struct x509_certificate *
  1287. x509_find_subject ( struct x509_chain *certs,
  1288. const struct asn1_cursor *subject ) {
  1289. struct x509_link *link;
  1290. struct x509_certificate *cert;
  1291. /* Scan through certificate list */
  1292. list_for_each_entry ( link, &certs->links, list ) {
  1293. /* Check subject */
  1294. cert = link->cert;
  1295. if ( asn1_compare ( subject, &cert->subject.raw ) == 0 )
  1296. return cert;
  1297. }
  1298. return NULL;
  1299. }
  1300. /**
  1301. * Append X.509 certificates to X.509 certificate chain
  1302. *
  1303. * @v chain X.509 certificate chain
  1304. * @v certs X.509 certificate list
  1305. * @ret rc Return status code
  1306. *
  1307. * Certificates will be automatically appended to the chain based upon
  1308. * the subject and issuer names.
  1309. */
  1310. int x509_auto_append ( struct x509_chain *chain, struct x509_chain *certs ) {
  1311. struct x509_certificate *cert;
  1312. struct x509_certificate *previous;
  1313. int rc;
  1314. /* Get current certificate */
  1315. cert = x509_last ( chain );
  1316. if ( ! cert ) {
  1317. DBGC ( chain, "X509 chain %p has no certificates\n", chain );
  1318. return -EACCES_EMPTY;
  1319. }
  1320. /* Append certificates, in order */
  1321. while ( 1 ) {
  1322. /* Find issuing certificate */
  1323. previous = cert;
  1324. cert = x509_find_subject ( certs, &cert->issuer.raw );
  1325. if ( ! cert )
  1326. break;
  1327. if ( cert == previous )
  1328. break;
  1329. /* Append certificate to chain */
  1330. if ( ( rc = x509_append ( chain, cert ) ) != 0 )
  1331. return rc;
  1332. }
  1333. return 0;
  1334. }
  1335. /**
  1336. * Validate X.509 certificate chain
  1337. *
  1338. * @v chain X.509 certificate chain
  1339. * @v time Time at which to validate certificates
  1340. * @v store Certificate store, or NULL to use default
  1341. * @v root Root certificate list, or NULL to use default
  1342. * @ret rc Return status code
  1343. */
  1344. int x509_validate_chain ( struct x509_chain *chain, time_t time,
  1345. struct x509_chain *store, struct x509_root *root ) {
  1346. struct x509_certificate *issuer = NULL;
  1347. struct x509_link *link;
  1348. int rc;
  1349. /* Use default certificate store if none specified */
  1350. if ( ! store )
  1351. store = &certstore;
  1352. /* Append any applicable certificates from the certificate store */
  1353. if ( ( rc = x509_auto_append ( chain, store ) ) != 0 )
  1354. return rc;
  1355. /* Find first certificate that can be validated as a
  1356. * standalone (i.e. is already valid, or can be validated as
  1357. * a trusted root certificate).
  1358. */
  1359. list_for_each_entry ( link, &chain->links, list ) {
  1360. /* Try validating this certificate as a standalone */
  1361. if ( ( rc = x509_validate ( link->cert, NULL, time,
  1362. root ) ) != 0 )
  1363. continue;
  1364. /* Work back up to start of chain, performing pairwise
  1365. * validation.
  1366. */
  1367. issuer = link->cert;
  1368. list_for_each_entry_continue_reverse ( link, &chain->links,
  1369. list ) {
  1370. /* Validate this certificate against its issuer */
  1371. if ( ( rc = x509_validate ( link->cert, issuer, time,
  1372. root ) ) != 0 )
  1373. return rc;
  1374. issuer = link->cert;
  1375. }
  1376. return 0;
  1377. }
  1378. DBGC ( chain, "X509 chain %p found no usable certificates\n", chain );
  1379. return -EACCES_USELESS;
  1380. }
  1381. /* Drag in certificate store */
  1382. REQUIRE_OBJECT ( certstore );