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

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