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 49KB

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