diff options
Diffstat (limited to 'lib/gnutls_x509.c')
-rw-r--r-- | lib/gnutls_x509.c | 155 |
1 files changed, 95 insertions, 60 deletions
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index aab25d8200..918ea66dcb 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -990,7 +990,7 @@ static int parse_der_cert_mem( gnutls_cert** cert_list, int* ncerts, memset( &cert_list[0][i - 1], 0, sizeof(gnutls_cert)); - tmp.data = (void*) input_cert; + tmp.data = (opaque*) input_cert; tmp.size = input_cert_size; if ((ret = @@ -1023,10 +1023,11 @@ static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts, i = *ncerts + 1; /* tmp now contains the decoded certificate list */ - tmp.data = (void*)input_cert; + tmp.data = (opaque*)input_cert; tmp.size = input_cert_size; count = gnutls_x509_pkcs7_extract_certificate_count( &tmp); + if (count < 0) { gnutls_assert(); /* if we failed to read the count, @@ -1090,7 +1091,7 @@ static int parse_pkcs7_cert_mem( gnutls_cert** cert_list, int* ncerts, /* Reads a base64 encoded certificate list from memory and stores it to * a gnutls_cert structure. Returns the number of certificate parsed. */ -static int parse_cert_mem( gnutls_cert** cert_list, int* ncerts, +static int parse_pem_cert_mem( gnutls_cert** cert_list, int* ncerts, const char *input_cert, int input_cert_size) { int siz, i, siz2; @@ -1200,7 +1201,7 @@ static int read_cert_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *cert, i ret = parse_pkcs7_cert_mem( &res->cert_list[res->ncerts], &res->cert_list_length[res->ncerts], cert, cert_size); else - ret = parse_cert_mem( &res->cert_list[res->ncerts], &res->cert_list_length[res->ncerts], + ret = parse_pem_cert_mem( &res->cert_list[res->ncerts], &res->cert_list_length[res->ncerts], cert, cert_size); if (ret < 0) { @@ -1222,12 +1223,51 @@ static int read_ca_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *ca, int c return parse_pkcs7_cert_mem( &res->x509_ca_list, &res->x509_ncas, ca, ca_size); else - return parse_cert_mem( &res->x509_ca_list, &res->x509_ncas, + return parse_pem_cert_mem( &res->x509_ca_list, &res->x509_ncas, ca, ca_size); } +/* This will check if the given DER key is a PKCS-1 RSA key. + */ +int _gnutls_der_check_if_rsa_key(const gnutls_datum * key_struct) +{ + node_asn *c2; + int result; + char root2[128]; + + /* Step 1. Parse content and content info */ + + if (key_struct->size == 0 || key_struct->data == NULL) { + gnutls_assert(); + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + + _gnutls_str_cpy( root2, sizeof(root2), "GNUTLS.RSAPrivateKey"); + if ((result=asn1_create_structure + (_gnutls_get_gnutls_asn(), root2, &c2, "rsakey")) != ASN_OK) { + gnutls_assert(); + return result; + } + + result = asn1_get_der(c2, key_struct->data, key_struct->size); + asn1_delete_structure(c2); + + if (result != ASN_OK) { + /* couldn't decode DER */ + + gnutls_assert(); + return result; + } + + return 0; +} + + + + + /* Reads a PEM encoded PKCS-1 RSA private key from memory * 2002-01-26: Added ability to read DSA keys. * type==0 then certificate is DER formatted, else -> DER @@ -1235,8 +1275,8 @@ static int read_ca_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *ca, int c static int read_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *key, int key_size, GNUTLS_X509_CertificateFmt type) { - int siz, ret; - opaque *b64; + int ret; + opaque *b64 = NULL; gnutls_datum tmp; PKAlgorithm pk; @@ -1249,22 +1289,22 @@ static int read_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *key, int } /* read PKCS-1 private key */ - siz = key_size; if (type==GNUTLS_X509_FMT_DER) { /* DER */ - - /* FIXME: only RSA keys supported - */ + int cv; + tmp.data = (opaque*)key; tmp.size = key_size; - - if ((ret = - _gnutls_PKCS1key2gnutlsKey(&res->pkey[res->ncerts], - tmp)) < 0) { - gnutls_assert(); - return ret; - } - + + /* The only way to distinguish the keys + * is to count the sequence of integers. + */ + cv = _gnutls_der_check_if_rsa_key( &tmp); + if (cv==0) + pk = GNUTLS_PK_RSA; + else + pk = GNUTLS_PK_DSA; + } else { /* PEM */ /* If we find the "DSA PRIVATE" string in the @@ -1275,39 +1315,42 @@ static int read_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *key, int else pk = GNUTLS_PK_RSA; - siz = _gnutls_fbase64_decode(key, siz, &b64); + ret = _gnutls_fbase64_decode(key, key_size, &b64); - if (siz < 0) { + if (ret < 0) { gnutls_assert(); return GNUTLS_E_PARSING_ERROR; } tmp.data = b64; - tmp.size = siz; - - switch (pk) { /* decode the key */ - case GNUTLS_PK_RSA: - if ((ret = - _gnutls_PKCS1key2gnutlsKey(&res->pkey[res->ncerts], + tmp.size = ret; + } + + switch (pk) { /* decode the key */ + case GNUTLS_PK_RSA: + if ((ret = + _gnutls_PKCS1key2gnutlsKey(&res->pkey[res->ncerts], + tmp)) < 0) { + gnutls_assert(); + gnutls_free(b64); + return ret; + } + break; + case GNUTLS_PK_DSA: + if ((ret = + _gnutls_DSAkey2gnutlsKey(&res->pkey[res->ncerts], tmp)) < 0) { - gnutls_assert(); - gnutls_free(b64); - return ret; - } - break; - case GNUTLS_PK_DSA: - if ((ret = - _gnutls_DSAkey2gnutlsKey(&res->pkey[res->ncerts], - tmp)) < 0) { - gnutls_assert(); - gnutls_free(b64); - return ret; - } - break; - } - - gnutls_free(b64); + gnutls_assert(); + gnutls_free(b64); + return ret; + } + break; } + + /* this doesn't hurt in the DER case, since + * b64 is NULL + */ + gnutls_free(b64); return 0; } @@ -1326,10 +1369,10 @@ static int read_cert_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *certfile, if (fd1 == NULL) return GNUTLS_E_FILE_ERROR; - siz = fread(x, 1, sizeof(x), fd1); + siz = fread(x, 1, sizeof(x)-1, fd1); fclose(fd1); - x[siz-1] = 0; + x[siz] = 0; return read_cert_mem( res, x, siz, type); @@ -1351,10 +1394,10 @@ static int read_ca_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *cafile, return GNUTLS_E_FILE_ERROR; } - siz = fread(x, 1, sizeof(x), fd1); + siz = fread(x, 1, sizeof(x)-1, fd1); fclose(fd1); - x[siz-1] = 0; + x[siz] = 0; return read_ca_mem( res, x, siz, type); } @@ -1374,10 +1417,10 @@ static int read_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *keyfile, if (fd2 == NULL) return GNUTLS_E_FILE_ERROR; - siz = fread(x, 1, sizeof(x), fd2); + siz = fread(x, 1, sizeof(x)-1, fd2); fclose(fd2); - x[siz-1] = 0; + x[siz] = 0; return read_key_mem( res, x, siz, type); } @@ -2072,10 +2115,10 @@ int _gnutls_verify_x509_file( char *cafile) return GNUTLS_E_FILE_ERROR; } - siz = fread(x, 1, sizeof(x), fd1); + siz = fread(x, 1, sizeof(x)-1, fd1); fclose(fd1); - x[siz-1] = 0; + x[siz] = 0; return _gnutls_verify_x509_mem( x, siz); } @@ -2128,8 +2171,6 @@ int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum * pkcs7_struct, int if (result != ASN_OK) { /* couldn't decode DER */ - _gnutls_log("X509_auth: Decoding error %d\n"); - gnutls_assert(); asn1_delete_structure(c1); return result; @@ -2184,8 +2225,6 @@ int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum * pkcs7_struct, int if (result != ASN_OK) { /* couldn't decode DER */ - _gnutls_log("X509_auth: Decoding error %d\n"); - gnutls_assert(); asn1_delete_structure(c2); return result; @@ -2408,8 +2447,6 @@ int gnutls_x509_pkcs7_extract_certificate_count(const gnutls_datum * pkcs7_struc if (result != ASN_OK) { /* couldn't decode DER */ - _gnutls_log("X509_auth: Decoding error %d\n"); - gnutls_assert(); asn1_delete_structure(c1); return result; @@ -2464,8 +2501,6 @@ int gnutls_x509_pkcs7_extract_certificate_count(const gnutls_datum * pkcs7_struc if (result != ASN_OK) { /* couldn't decode DER */ - _gnutls_log("X509_auth: Decoding error %d\n"); - gnutls_assert(); asn1_delete_structure(c2); return result; |