x509_csr.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. /*
  2. * X.509 Certificate Signing Request (CSR) parsing
  3. *
  4. * Copyright (C) 2006-2014, Brainspark B.V.
  5. *
  6. * This file is part of PolarSSL (http://www.polarssl.org)
  7. * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
  8. *
  9. * All rights reserved.
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License along
  22. * with this program; if not, write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  24. */
  25. /*
  26. * The ITU-T X.509 standard defines a certificate format for PKI.
  27. *
  28. * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
  29. * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
  30. * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
  31. *
  32. * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
  33. * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  34. */
  35. #if !defined(POLARSSL_CONFIG_FILE)
  36. #include "polarssl/config.h"
  37. #else
  38. #include POLARSSL_CONFIG_FILE
  39. #endif
  40. #if defined(POLARSSL_X509_CSR_PARSE_C)
  41. #include "polarssl/x509_csr.h"
  42. #include "polarssl/oid.h"
  43. #if defined(POLARSSL_PEM_PARSE_C)
  44. #include "polarssl/pem.h"
  45. #endif
  46. #if defined(POLARSSL_PLATFORM_C)
  47. #include "polarssl/platform.h"
  48. #else
  49. #define polarssl_malloc malloc
  50. #define polarssl_free free
  51. #endif
  52. #include <string.h>
  53. #include <stdlib.h>
  54. #if defined(POLARSSL_FS_IO) || defined(EFIX64) || defined(EFI32)
  55. #include <stdio.h>
  56. #endif
  57. /* Implementation that should never be optimized out by the compiler */
  58. static void polarssl_zeroize( void *v, size_t n ) {
  59. volatile unsigned char *p = v; while( n-- ) *p++ = 0;
  60. }
  61. /*
  62. * Version ::= INTEGER { v1(0) }
  63. */
  64. static int x509_csr_get_version( unsigned char **p,
  65. const unsigned char *end,
  66. int *ver )
  67. {
  68. int ret;
  69. if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
  70. {
  71. if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
  72. {
  73. *ver = 0;
  74. return( 0 );
  75. }
  76. return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
  77. }
  78. return( 0 );
  79. }
  80. /*
  81. * Parse a CSR in DER format
  82. */
  83. int x509_csr_parse_der( x509_csr *csr,
  84. const unsigned char *buf, size_t buflen )
  85. {
  86. int ret;
  87. size_t len;
  88. unsigned char *p, *end;
  89. x509_buf sig_params;
  90. memset( &sig_params, 0, sizeof( x509_buf ) );
  91. /*
  92. * Check for valid input
  93. */
  94. if( csr == NULL || buf == NULL )
  95. return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
  96. x509_csr_init( csr );
  97. /*
  98. * first copy the raw DER data
  99. */
  100. p = (unsigned char *) polarssl_malloc( len = buflen );
  101. if( p == NULL )
  102. return( POLARSSL_ERR_X509_MALLOC_FAILED );
  103. memcpy( p, buf, buflen );
  104. csr->raw.p = p;
  105. csr->raw.len = len;
  106. end = p + len;
  107. /*
  108. * CertificationRequest ::= SEQUENCE {
  109. * certificationRequestInfo CertificationRequestInfo,
  110. * signatureAlgorithm AlgorithmIdentifier,
  111. * signature BIT STRING
  112. * }
  113. */
  114. if( ( ret = asn1_get_tag( &p, end, &len,
  115. ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
  116. {
  117. x509_csr_free( csr );
  118. return( POLARSSL_ERR_X509_INVALID_FORMAT );
  119. }
  120. if( len != (size_t) ( end - p ) )
  121. {
  122. x509_csr_free( csr );
  123. return( POLARSSL_ERR_X509_INVALID_FORMAT +
  124. POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
  125. }
  126. /*
  127. * CertificationRequestInfo ::= SEQUENCE {
  128. */
  129. csr->cri.p = p;
  130. if( ( ret = asn1_get_tag( &p, end, &len,
  131. ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
  132. {
  133. x509_csr_free( csr );
  134. return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
  135. }
  136. end = p + len;
  137. csr->cri.len = end - csr->cri.p;
  138. /*
  139. * Version ::= INTEGER { v1(0) }
  140. */
  141. if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
  142. {
  143. x509_csr_free( csr );
  144. return( ret );
  145. }
  146. csr->version++;
  147. if( csr->version != 1 )
  148. {
  149. x509_csr_free( csr );
  150. return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
  151. }
  152. /*
  153. * subject Name
  154. */
  155. csr->subject_raw.p = p;
  156. if( ( ret = asn1_get_tag( &p, end, &len,
  157. ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
  158. {
  159. x509_csr_free( csr );
  160. return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
  161. }
  162. if( ( ret = x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
  163. {
  164. x509_csr_free( csr );
  165. return( ret );
  166. }
  167. csr->subject_raw.len = p - csr->subject_raw.p;
  168. /*
  169. * subjectPKInfo SubjectPublicKeyInfo
  170. */
  171. if( ( ret = pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 )
  172. {
  173. x509_csr_free( csr );
  174. return( ret );
  175. }
  176. /*
  177. * attributes [0] Attributes
  178. */
  179. if( ( ret = asn1_get_tag( &p, end, &len,
  180. ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ) != 0 )
  181. {
  182. x509_csr_free( csr );
  183. return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
  184. }
  185. // TODO Parse Attributes / extension requests
  186. p += len;
  187. end = csr->raw.p + csr->raw.len;
  188. /*
  189. * signatureAlgorithm AlgorithmIdentifier,
  190. * signature BIT STRING
  191. */
  192. if( ( ret = x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 )
  193. {
  194. x509_csr_free( csr );
  195. return( ret );
  196. }
  197. if( ( ret = x509_get_sig_alg( &csr->sig_oid, &sig_params,
  198. &csr->sig_md, &csr->sig_pk,
  199. &csr->sig_opts ) ) != 0 )
  200. {
  201. x509_csr_free( csr );
  202. return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
  203. }
  204. if( ( ret = x509_get_sig( &p, end, &csr->sig ) ) != 0 )
  205. {
  206. x509_csr_free( csr );
  207. return( ret );
  208. }
  209. if( p != end )
  210. {
  211. x509_csr_free( csr );
  212. return( POLARSSL_ERR_X509_INVALID_FORMAT +
  213. POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
  214. }
  215. return( 0 );
  216. }
  217. /*
  218. * Parse a CSR, allowing for PEM or raw DER encoding
  219. */
  220. int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen )
  221. {
  222. int ret;
  223. #if defined(POLARSSL_PEM_PARSE_C)
  224. size_t use_len;
  225. pem_context pem;
  226. #endif
  227. /*
  228. * Check for valid input
  229. */
  230. if( csr == NULL || buf == NULL )
  231. return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
  232. #if defined(POLARSSL_PEM_PARSE_C)
  233. pem_init( &pem );
  234. ret = pem_read_buffer( &pem,
  235. "-----BEGIN CERTIFICATE REQUEST-----",
  236. "-----END CERTIFICATE REQUEST-----",
  237. buf, NULL, 0, &use_len );
  238. if( ret == 0 )
  239. {
  240. /*
  241. * Was PEM encoded, parse the result
  242. */
  243. if( ( ret = x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 )
  244. return( ret );
  245. pem_free( &pem );
  246. return( 0 );
  247. }
  248. else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
  249. {
  250. pem_free( &pem );
  251. return( ret );
  252. }
  253. else
  254. #endif /* POLARSSL_PEM_PARSE_C */
  255. return( x509_csr_parse_der( csr, buf, buflen ) );
  256. }
  257. #if defined(POLARSSL_FS_IO)
  258. /*
  259. * Load a CSR into the structure
  260. */
  261. int x509_csr_parse_file( x509_csr *csr, const char *path )
  262. {
  263. int ret;
  264. size_t n;
  265. unsigned char *buf;
  266. if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
  267. return( ret );
  268. ret = x509_csr_parse( csr, buf, n );
  269. polarssl_zeroize( buf, n + 1 );
  270. polarssl_free( buf );
  271. return( ret );
  272. }
  273. #endif /* POLARSSL_FS_IO */
  274. #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
  275. !defined(EFI32)
  276. #include <stdarg.h>
  277. #if !defined vsnprintf
  278. #define vsnprintf _vsnprintf
  279. #endif // vsnprintf
  280. /*
  281. * Windows _snprintf and _vsnprintf are not compatible to linux versions.
  282. * Result value is not size of buffer needed, but -1 if no fit is possible.
  283. *
  284. * This fuction tries to 'fix' this by at least suggesting enlarging the
  285. * size by 20.
  286. */
  287. static int compat_snprintf( char *str, size_t size, const char *format, ... )
  288. {
  289. va_list ap;
  290. int res = -1;
  291. va_start( ap, format );
  292. res = vsnprintf( str, size, format, ap );
  293. va_end( ap );
  294. // No quick fix possible
  295. if( res < 0 )
  296. return( (int) size + 20 );
  297. return( res );
  298. }
  299. #define snprintf compat_snprintf
  300. #endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */
  301. #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
  302. #define SAFE_SNPRINTF() \
  303. { \
  304. if( ret == -1 ) \
  305. return( -1 ); \
  306. \
  307. if( (unsigned int) ret > n ) { \
  308. p[n - 1] = '\0'; \
  309. return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
  310. } \
  311. \
  312. n -= (unsigned int) ret; \
  313. p += (unsigned int) ret; \
  314. }
  315. #define BEFORE_COLON 14
  316. #define BC "14"
  317. /*
  318. * Return an informational string about the CSR.
  319. */
  320. int x509_csr_info( char *buf, size_t size, const char *prefix,
  321. const x509_csr *csr )
  322. {
  323. int ret;
  324. size_t n;
  325. char *p;
  326. char key_size_str[BEFORE_COLON];
  327. p = buf;
  328. n = size;
  329. ret = snprintf( p, n, "%sCSR version : %d",
  330. prefix, csr->version );
  331. SAFE_SNPRINTF();
  332. ret = snprintf( p, n, "\n%ssubject name : ", prefix );
  333. SAFE_SNPRINTF();
  334. ret = x509_dn_gets( p, n, &csr->subject );
  335. SAFE_SNPRINTF();
  336. ret = snprintf( p, n, "\n%ssigned using : ", prefix );
  337. SAFE_SNPRINTF();
  338. ret = x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
  339. csr->sig_opts );
  340. SAFE_SNPRINTF();
  341. if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
  342. pk_get_name( &csr->pk ) ) ) != 0 )
  343. {
  344. return( ret );
  345. }
  346. ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
  347. (int) pk_get_size( &csr->pk ) );
  348. SAFE_SNPRINTF();
  349. return( (int) ( size - n ) );
  350. }
  351. /*
  352. * Initialize a CSR
  353. */
  354. void x509_csr_init( x509_csr *csr )
  355. {
  356. memset( csr, 0, sizeof(x509_csr) );
  357. }
  358. /*
  359. * Unallocate all CSR data
  360. */
  361. void x509_csr_free( x509_csr *csr )
  362. {
  363. x509_name *name_cur;
  364. x509_name *name_prv;
  365. if( csr == NULL )
  366. return;
  367. pk_free( &csr->pk );
  368. #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
  369. polarssl_free( csr->sig_opts );
  370. #endif
  371. name_cur = csr->subject.next;
  372. while( name_cur != NULL )
  373. {
  374. name_prv = name_cur;
  375. name_cur = name_cur->next;
  376. polarssl_zeroize( name_prv, sizeof( x509_name ) );
  377. polarssl_free( name_prv );
  378. }
  379. if( csr->raw.p != NULL )
  380. {
  381. polarssl_zeroize( csr->raw.p, csr->raw.len );
  382. polarssl_free( csr->raw.p );
  383. }
  384. polarssl_zeroize( csr, sizeof( x509_csr ) );
  385. }
  386. #endif /* POLARSSL_X509_CSR_PARSE_C */