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