int main( int argc, char *argv[] ) { int ret = 0; unsigned char buf[100000]; x509_csr csr; int i, j, n; char *p, *q; /* * Set to sane values */ x509_csr_init( &csr ); if( argc == 0 ) { usage: printf( USAGE ); goto exit; } opt.filename = DFL_FILENAME; for( i = 1; i < argc; i++ ) { n = strlen( argv[i] ); for( j = 0; j < n; j++ ) { if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' ) argv[i][j] |= 0x20; } p = argv[i]; if( ( q = strchr( p, '=' ) ) == NULL ) goto usage; *q++ = '\0'; if( strcmp( p, "filename" ) == 0 ) opt.filename = q; else goto usage; } /* * 1.1. Load the CSR */ printf( "\n . Loading the CSR ..." ); fflush( stdout ); ret = x509_csr_parse_file( &csr, opt.filename ); if( ret != 0 ) { printf( " failed\n ! x509_csr_parse_file returned %d\n\n", ret ); x509_csr_free( &csr ); goto exit; } printf( " ok\n" ); /* * 1.2 Print the CSR */ printf( " . CSR information ...\n" ); ret = x509_csr_info( (char *) buf, sizeof( buf ) - 1, " ", &csr ); if( ret == -1 ) { printf( " failed\n ! x509_csr_info returned %d\n\n", ret ); x509_csr_free( &csr ); goto exit; } printf( "%s\n", buf ); exit: x509_csr_free( &csr ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
/* * Parse a CSR */ int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) { int ret; size_t len; unsigned char *p, *end; #if defined(POLARSSL_PEM_PARSE_C) size_t use_len; pem_context pem; #endif /* * Check for valid input */ if( csr == NULL || buf == NULL ) return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); x509_csr_init( csr ); #if defined(POLARSSL_PEM_PARSE_C) pem_init( &pem ); ret = pem_read_buffer( &pem, "-----BEGIN CERTIFICATE REQUEST-----", "-----END CERTIFICATE REQUEST-----", buf, NULL, 0, &use_len ); if( ret == 0 ) { /* * Was PEM encoded */ buflen -= use_len; buf += use_len; /* * Steal PEM buffer */ p = pem.buf; pem.buf = NULL; len = pem.buflen; pem_free( &pem ); } else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) { pem_free( &pem ); return( ret ); } else #endif { /* * nope, copy the raw DER data */ p = (unsigned char *) polarssl_malloc( len = buflen ); if( p == NULL ) return( POLARSSL_ERR_X509_MALLOC_FAILED ); memcpy( p, buf, buflen ); buflen = 0; } csr->raw.p = p; csr->raw.len = len; end = p + len; /* * CertificationRequest ::= SEQUENCE { * certificationRequestInfo CertificationRequestInfo, * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING * } */ if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT ); } if( len != (size_t) ( end - p ) ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); } /* * CertificationRequestInfo ::= SEQUENCE { */ csr->cri.p = p; if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); } end = p + len; csr->cri.len = end - csr->cri.p; /* * Version ::= INTEGER { v1(0) } */ if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } csr->version++; if( csr->version != 1 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_UNKNOWN_VERSION ); } /* * subject Name */ csr->subject_raw.p = p; if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); } if( ( ret = x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } csr->subject_raw.len = p - csr->subject_raw.p; /* * subjectPKInfo SubjectPublicKeyInfo */ if( ( ret = pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } /* * attributes [0] Attributes */ if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); } // TODO Parse Attributes / extension requests p += len; end = csr->raw.p + csr->raw.len; /* * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING */ if( ( ret = x509_get_alg_null( &p, end, &csr->sig_oid ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } if( ( ret = x509_get_sig_alg( &csr->sig_oid, &csr->sig_md, &csr->sig_pk ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG ); } if( ( ret = x509_get_sig( &p, end, &csr->sig ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } if( p != end ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); } return( 0 ); }
void X509Req::clear() { x509_csr_free(&m_csr); x509_csr_init(&m_csr); }
/* * Parse a CSR in DER format */ int x509_csr_parse_der( x509_csr *csr, const unsigned char *buf, size_t buflen ) { int ret; size_t len; unsigned char *p, *end; x509_buf sig_params; memset( &sig_params, 0, sizeof( x509_buf ) ); /* * Check for valid input */ if( csr == NULL || buf == NULL ) return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); x509_csr_init( csr ); /* * first copy the raw DER data */ p = polarssl_malloc( len = buflen ); if( p == NULL ) return( POLARSSL_ERR_X509_MALLOC_FAILED ); memcpy( p, buf, buflen ); csr->raw.p = p; csr->raw.len = len; end = p + len; /* * CertificationRequest ::= SEQUENCE { * certificationRequestInfo CertificationRequestInfo, * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING * } */ if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT ); } if( len != (size_t) ( end - p ) ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); } /* * CertificationRequestInfo ::= SEQUENCE { */ csr->cri.p = p; if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); } end = p + len; csr->cri.len = end - csr->cri.p; /* * Version ::= INTEGER { v1(0) } */ if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } if( csr->version != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_UNKNOWN_VERSION ); } csr->version++; /* * subject Name */ csr->subject_raw.p = p; if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); } if( ( ret = x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } csr->subject_raw.len = p - csr->subject_raw.p; /* * subjectPKInfo SubjectPublicKeyInfo */ if( ( ret = pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } /* * attributes [0] Attributes */ if( ( ret = asn1_get_tag( &p, end, &len, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); } // TODO Parse Attributes / extension requests p += len; end = csr->raw.p + csr->raw.len; /* * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING */ if( ( ret = x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } if( ( ret = x509_get_sig_alg( &csr->sig_oid, &sig_params, &csr->sig_md, &csr->sig_pk, &csr->sig_opts ) ) != 0 ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG ); } if( ( ret = x509_get_sig( &p, end, &csr->sig ) ) != 0 ) { x509_csr_free( csr ); return( ret ); } if( p != end ) { x509_csr_free( csr ); return( POLARSSL_ERR_X509_INVALID_FORMAT + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); } return( 0 ); }
X509Req::~X509Req() { x509_csr_free(&m_csr); }