Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  *  X.509 Certificate Signing Request (CSR) parsing
  3.  *
  4.  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
  5.  *  SPDX-License-Identifier: GPL-2.0
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License along
  18.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  19.  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  *  This file is part of mbed TLS (https://tls.mbed.org)
  22.  */
  23. /*
  24.  *  The ITU-T X.509 standard defines a certificate format for PKI.
  25.  *
  26.  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
  27.  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
  28.  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
  29.  *
  30.  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
  31.  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
  32.  */
  33.  
  34. #if !defined(MBEDTLS_CONFIG_FILE)
  35. #include "mbedtls/config.h"
  36. #else
  37. #include MBEDTLS_CONFIG_FILE
  38. #endif
  39.  
  40. #if defined(MBEDTLS_X509_CSR_PARSE_C)
  41.  
  42. #include "mbedtls/x509_csr.h"
  43. #include "mbedtls/oid.h"
  44. #include "mbedtls/platform_util.h"
  45.  
  46. #include <string.h>
  47.  
  48. #if defined(MBEDTLS_PEM_PARSE_C)
  49. #include "mbedtls/pem.h"
  50. #endif
  51.  
  52. #if defined(MBEDTLS_PLATFORM_C)
  53. #include "mbedtls/platform.h"
  54. #else
  55. #include <stdlib.h>
  56. #include <stdio.h>
  57. #define mbedtls_free       free
  58. #define mbedtls_calloc    calloc
  59. #define mbedtls_snprintf   snprintf
  60. #endif
  61.  
  62. #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
  63. #include <stdio.h>
  64. #endif
  65.  
  66. /*
  67.  *  Version  ::=  INTEGER  {  v1(0)  }
  68.  */
  69. static int x509_csr_get_version( unsigned char **p,
  70.                              const unsigned char *end,
  71.                              int *ver )
  72. {
  73.     int ret;
  74.  
  75.     if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
  76.     {
  77.         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
  78.         {
  79.             *ver = 0;
  80.             return( 0 );
  81.         }
  82.  
  83.         return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
  84.     }
  85.  
  86.     return( 0 );
  87. }
  88.  
  89. /*
  90.  * Parse a CSR in DER format
  91.  */
  92. int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
  93.                         const unsigned char *buf, size_t buflen )
  94. {
  95.     int ret;
  96.     size_t len;
  97.     unsigned char *p, *end;
  98.     mbedtls_x509_buf sig_params;
  99.  
  100.     memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) );
  101.  
  102.     /*
  103.      * Check for valid input
  104.      */
  105.     if( csr == NULL || buf == NULL || buflen == 0 )
  106.         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
  107.  
  108.     mbedtls_x509_csr_init( csr );
  109.  
  110.     /*
  111.      * first copy the raw DER data
  112.      */
  113.     p = mbedtls_calloc( 1, len = buflen );
  114.  
  115.     if( p == NULL )
  116.         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
  117.  
  118.     memcpy( p, buf, buflen );
  119.  
  120.     csr->raw.p = p;
  121.     csr->raw.len = len;
  122.     end = p + len;
  123.  
  124.     /*
  125.      *  CertificationRequest ::= SEQUENCE {
  126.      *       certificationRequestInfo CertificationRequestInfo,
  127.      *       signatureAlgorithm AlgorithmIdentifier,
  128.      *       signature          BIT STRING
  129.      *  }
  130.      */
  131.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
  132.             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
  133.     {
  134.         mbedtls_x509_csr_free( csr );
  135.         return( MBEDTLS_ERR_X509_INVALID_FORMAT );
  136.     }
  137.  
  138.     if( len != (size_t) ( end - p ) )
  139.     {
  140.         mbedtls_x509_csr_free( csr );
  141.         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
  142.                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  143.     }
  144.  
  145.     /*
  146.      *  CertificationRequestInfo ::= SEQUENCE {
  147.      */
  148.     csr->cri.p = p;
  149.  
  150.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
  151.             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
  152.     {
  153.         mbedtls_x509_csr_free( csr );
  154.         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
  155.     }
  156.  
  157.     end = p + len;
  158.     csr->cri.len = end - csr->cri.p;
  159.  
  160.     /*
  161.      *  Version  ::=  INTEGER {  v1(0) }
  162.      */
  163.     if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
  164.     {
  165.         mbedtls_x509_csr_free( csr );
  166.         return( ret );
  167.     }
  168.  
  169.     if( csr->version != 0 )
  170.     {
  171.         mbedtls_x509_csr_free( csr );
  172.         return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
  173.     }
  174.  
  175.     csr->version++;
  176.  
  177.     /*
  178.      *  subject               Name
  179.      */
  180.     csr->subject_raw.p = p;
  181.  
  182.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
  183.             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
  184.     {
  185.         mbedtls_x509_csr_free( csr );
  186.         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
  187.     }
  188.  
  189.     if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
  190.     {
  191.         mbedtls_x509_csr_free( csr );
  192.         return( ret );
  193.     }
  194.  
  195.     csr->subject_raw.len = p - csr->subject_raw.p;
  196.  
  197.     /*
  198.      *  subjectPKInfo SubjectPublicKeyInfo
  199.      */
  200.     if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 )
  201.     {
  202.         mbedtls_x509_csr_free( csr );
  203.         return( ret );
  204.     }
  205.  
  206.     /*
  207.      *  attributes    [0] Attributes
  208.      *
  209.      *  The list of possible attributes is open-ended, though RFC 2985
  210.      *  (PKCS#9) defines a few in section 5.4. We currently don't support any,
  211.      *  so we just ignore them. This is a safe thing to do as the worst thing
  212.      *  that could happen is that we issue a certificate that does not match
  213.      *  the requester's expectations - this cannot cause a violation of our
  214.      *  signature policies.
  215.      */
  216.     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
  217.             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
  218.     {
  219.         mbedtls_x509_csr_free( csr );
  220.         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
  221.     }
  222.  
  223.     p += len;
  224.  
  225.     end = csr->raw.p + csr->raw.len;
  226.  
  227.     /*
  228.      *  signatureAlgorithm   AlgorithmIdentifier,
  229.      *  signature            BIT STRING
  230.      */
  231.     if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 )
  232.     {
  233.         mbedtls_x509_csr_free( csr );
  234.         return( ret );
  235.     }
  236.  
  237.     if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params,
  238.                                   &csr->sig_md, &csr->sig_pk,
  239.                                   &csr->sig_opts ) ) != 0 )
  240.     {
  241.         mbedtls_x509_csr_free( csr );
  242.         return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
  243.     }
  244.  
  245.     if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 )
  246.     {
  247.         mbedtls_x509_csr_free( csr );
  248.         return( ret );
  249.     }
  250.  
  251.     if( p != end )
  252.     {
  253.         mbedtls_x509_csr_free( csr );
  254.         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
  255.                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  256.     }
  257.  
  258.     return( 0 );
  259. }
  260.  
  261. /*
  262.  * Parse a CSR, allowing for PEM or raw DER encoding
  263.  */
  264. int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen )
  265. {
  266. #if defined(MBEDTLS_PEM_PARSE_C)
  267.     int ret;
  268.     size_t use_len;
  269.     mbedtls_pem_context pem;
  270. #endif
  271.  
  272.     /*
  273.      * Check for valid input
  274.      */
  275.     if( csr == NULL || buf == NULL || buflen == 0 )
  276.         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
  277.  
  278. #if defined(MBEDTLS_PEM_PARSE_C)
  279.     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
  280.     if( buf[buflen - 1] == '\0' )
  281.     {
  282.         mbedtls_pem_init( &pem );
  283.         ret = mbedtls_pem_read_buffer( &pem,
  284.                                        "-----BEGIN CERTIFICATE REQUEST-----",
  285.                                        "-----END CERTIFICATE REQUEST-----",
  286.                                        buf, NULL, 0, &use_len );
  287.         if( ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
  288.         {
  289.             ret = mbedtls_pem_read_buffer( &pem,
  290.                                            "-----BEGIN NEW CERTIFICATE REQUEST-----",
  291.                                            "-----END NEW CERTIFICATE REQUEST-----",
  292.                                            buf, NULL, 0, &use_len );
  293.         }
  294.  
  295.         if( ret == 0 )
  296.         {
  297.             /*
  298.              * Was PEM encoded, parse the result
  299.              */
  300.             ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen );
  301.         }
  302.  
  303.         mbedtls_pem_free( &pem );
  304.         if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
  305.             return( ret );
  306.     }
  307. #endif /* MBEDTLS_PEM_PARSE_C */
  308.     return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) );
  309. }
  310.  
  311. #if defined(MBEDTLS_FS_IO)
  312. /*
  313.  * Load a CSR into the structure
  314.  */
  315. int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
  316. {
  317.     int ret;
  318.     size_t n;
  319.     unsigned char *buf;
  320.  
  321.     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
  322.         return( ret );
  323.  
  324.     ret = mbedtls_x509_csr_parse( csr, buf, n );
  325.  
  326.     mbedtls_platform_zeroize( buf, n );
  327.     mbedtls_free( buf );
  328.  
  329.     return( ret );
  330. }
  331. #endif /* MBEDTLS_FS_IO */
  332.  
  333. #define BEFORE_COLON    14
  334. #define BC              "14"
  335. /*
  336.  * Return an informational string about the CSR.
  337.  */
  338. int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
  339.                    const mbedtls_x509_csr *csr )
  340. {
  341.     int ret;
  342.     size_t n;
  343.     char *p;
  344.     char key_size_str[BEFORE_COLON];
  345.  
  346.     p = buf;
  347.     n = size;
  348.  
  349.     ret = mbedtls_snprintf( p, n, "%sCSR version   : %d",
  350.                                prefix, csr->version );
  351.     MBEDTLS_X509_SAFE_SNPRINTF;
  352.  
  353.     ret = mbedtls_snprintf( p, n, "\n%ssubject name  : ", prefix );
  354.     MBEDTLS_X509_SAFE_SNPRINTF;
  355.     ret = mbedtls_x509_dn_gets( p, n, &csr->subject );
  356.     MBEDTLS_X509_SAFE_SNPRINTF;
  357.  
  358.     ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
  359.     MBEDTLS_X509_SAFE_SNPRINTF;
  360.  
  361.     ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
  362.                              csr->sig_opts );
  363.     MBEDTLS_X509_SAFE_SNPRINTF;
  364.  
  365.     if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
  366.                                       mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
  367.     {
  368.         return( ret );
  369.     }
  370.  
  371.     ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
  372.                           (int) mbedtls_pk_get_bitlen( &csr->pk ) );
  373.     MBEDTLS_X509_SAFE_SNPRINTF;
  374.  
  375.     return( (int) ( size - n ) );
  376. }
  377.  
  378. /*
  379.  * Initialize a CSR
  380.  */
  381. void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
  382. {
  383.     memset( csr, 0, sizeof(mbedtls_x509_csr) );
  384. }
  385.  
  386. /*
  387.  * Unallocate all CSR data
  388.  */
  389. void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
  390. {
  391.     mbedtls_x509_name *name_cur;
  392.     mbedtls_x509_name *name_prv;
  393.  
  394.     if( csr == NULL )
  395.         return;
  396.  
  397.     mbedtls_pk_free( &csr->pk );
  398.  
  399. #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
  400.     mbedtls_free( csr->sig_opts );
  401. #endif
  402.  
  403.     name_cur = csr->subject.next;
  404.     while( name_cur != NULL )
  405.     {
  406.         name_prv = name_cur;
  407.         name_cur = name_cur->next;
  408.         mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
  409.         mbedtls_free( name_prv );
  410.     }
  411.  
  412.     if( csr->raw.p != NULL )
  413.     {
  414.         mbedtls_platform_zeroize( csr->raw.p, csr->raw.len );
  415.         mbedtls_free( csr->raw.p );
  416.     }
  417.  
  418.     mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) );
  419. }
  420.  
  421. #endif /* MBEDTLS_X509_CSR_PARSE_C */
  422.