From: Nikos Mavrogiannopoulos Date: Fri, 22 Jun 2001 20:59:50 +0000 (+0000) Subject: added internal representation of pkcs1 rsa private keys. X-Git-Tag: gnutls_0_1_9~79 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0103cc1f3e2cdf6fdf27ea76b237e93a3fae4472;p=thirdparty%2Fgnutls.git added internal representation of pkcs1 rsa private keys. --- diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index 5e06f44a2d..c0e443f4ef 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -35,25 +35,25 @@ int gen_rsa_certificate(GNUTLS_KEY, opaque **); int gen_rsa_client_kx(GNUTLS_KEY, opaque **); -int proc_rsa_client_kx( GNUTLS_KEY, opaque*, int); -int proc_rsa_certificate( GNUTLS_KEY, opaque*, int); +int proc_rsa_client_kx(GNUTLS_KEY, opaque *, int); +int proc_rsa_certificate(GNUTLS_KEY, opaque *, int); MOD_AUTH_STRUCT rsa_auth_struct = { "RSA", gen_rsa_certificate, - NULL, /* gen server kx */ - NULL, /* gen server kx2 */ - NULL, /* gen client kx0 */ + NULL, /* gen server kx */ + NULL, /* gen server kx2 */ + NULL, /* gen client kx0 */ gen_rsa_client_kx, - NULL, /* gen client cert vrfy */ - NULL, /* gen server cert vrfy */ + NULL, /* gen client cert vrfy */ + NULL, /* gen server cert vrfy */ proc_rsa_certificate, - NULL, /* proc server kx */ - NULL, /* proc server kx2 */ - NULL, /* proc client kx0 */ - proc_rsa_client_kx, /* proc client kx */ - NULL, /* proc client cert vrfy */ - NULL /* proc server cert vrfy */ + NULL, /* proc server kx */ + NULL, /* proc server kx2 */ + NULL, /* proc client kx0 */ + proc_rsa_client_kx, /* proc client kx */ + NULL, /* proc client cert vrfy */ + NULL /* proc server cert vrfy */ }; typedef struct { @@ -64,13 +64,15 @@ typedef struct { /* This function extracts the RSA parameters from the given(?) certificate. */ -static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, MPI* mod, MPI* exp, gnutls_datum cert) +static int _gnutls_get_rsa_params(GNUTLS_KEY key, RSA_Params * params, + MPI * mod, MPI * exp, gnutls_datum cert) { int ret = 0, result; - opaque str[5*1024]; + opaque str[5 * 1024]; int len = sizeof(str); - if (create_structure("rsa_params", "PKIX1Explicit88.Certificate")!=ASN_OK) { + if (create_structure("rsa_params", "PKIX1Explicit88.Certificate") + != ASN_OK) { gnutls_assert(); return GNUTLS_E_ASN1_ERROR; } @@ -85,7 +87,9 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, MPI* mod len = sizeof(str); result = - read_value("rsa_params.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", str, &len); + read_value + ("rsa_params.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", + str, &len); if (result != ASN_OK) { gnutls_assert(); @@ -93,10 +97,12 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, MPI* mod return GNUTLS_E_ASN1_PARSING_ERROR; } - if (!strcmp(str, "1 2 840 113549 1 1 1")) { /* pkix-1 1 - RSA */ + if (!strcmp(str, "1 2 840 113549 1 1 1")) { /* pkix-1 1 - RSA */ len = sizeof(str); result = - read_value("rsa_params.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", str, &len); + read_value + ("rsa_params.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", + str, &len); delete_structure("rsa_params"); if (result != ASN_OK) { @@ -104,37 +110,38 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, MPI* mod return GNUTLS_E_ASN1_PARSING_ERROR; } - if (create_structure("rsa_public_key", "PKIX1Explicit88.RSAPublicKey")!=ASN_OK) { + if (create_structure + ("rsa_public_key", + "PKIX1Explicit88.RSAPublicKey") != ASN_OK) { gnutls_assert(); return GNUTLS_E_ASN1_ERROR; } - result = get_der("rsa_public_key", str, len/8); + result = get_der("rsa_public_key", str, len / 8); if (result != ASN_OK) { gnutls_assert(); delete_structure("rsa_public_key"); return GNUTLS_E_ASN1_PARSING_ERROR; - } + } len = sizeof(str); - result = - read_value("rsa_public_key.modulus", str, &len); + result = read_value("rsa_public_key.modulus", str, &len); if (result != ASN_OK) { gnutls_assert(); delete_structure("rsa_public_key"); return GNUTLS_E_ASN1_PARSING_ERROR; } - if (gcry_mpi_scan(mod, - GCRYMPI_FMT_USG, str, &len) != 0) { + if (gcry_mpi_scan(mod, GCRYMPI_FMT_USG, str, &len) != 0) { gnutls_assert(); delete_structure("rsa_public_key"); return GNUTLS_E_MPI_SCAN_FAILED; } - - if (params!=NULL) - if (gnutls_set_datum(¶ms->rsa_modulus, str, len) < 0) { + + if (params != NULL) + if (gnutls_set_datum + (¶ms->rsa_modulus, str, len) < 0) { gnutls_assert(); delete_structure("rsa_public_key"); return GNUTLS_E_MEMORY_ERROR; @@ -146,32 +153,36 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, MPI* mod if (result != ASN_OK) { gnutls_assert(); delete_structure("rsa_public_key"); - if (params!=NULL) gnutls_free_datum(¶ms->rsa_modulus); + if (params != NULL) + gnutls_free_datum(¶ms->rsa_modulus); _gnutls_mpi_release(mod); return GNUTLS_E_ASN1_PARSING_ERROR; } - if (gcry_mpi_scan(exp, - GCRYMPI_FMT_USG, str, &len) != 0) { + if (gcry_mpi_scan(exp, GCRYMPI_FMT_USG, str, &len) != 0) { gnutls_assert(); _gnutls_mpi_release(mod); - if (params!=NULL) gnutls_free_datum(¶ms->rsa_modulus); + if (params != NULL) + gnutls_free_datum(¶ms->rsa_modulus); delete_structure("rsa_public_key"); return GNUTLS_E_MPI_SCAN_FAILED; } - if (params !=NULL) - if (gnutls_set_datum(¶ms->rsa_exponent, str, len) < 0) { + if (params != NULL) + if (gnutls_set_datum + (¶ms->rsa_exponent, str, len) < 0) { _gnutls_mpi_release(mod); _gnutls_mpi_release(exp); - if (params!=NULL) gnutls_free_datum(¶ms->rsa_modulus); + if (params != NULL) + gnutls_free_datum(¶ms-> + rsa_modulus); delete_structure("rsa_public_key"); - return GNUTLS_E_MEMORY_ERROR; + return GNUTLS_E_MEMORY_ERROR; } delete_structure("rsa_public_key"); - + ret = 0; - + } else { /* The certificate that was sent was not * supported by the ciphersuite @@ -189,61 +200,17 @@ static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, MPI* mod /* This function reads the RSA parameters from the given private key * cert is not a certificate but a der structure containing the private * key(s). + * Ok this is no longer the case. We now precompile the pkcs1 key + * to the gnutls_private_key structure. */ -static int _gnutls_get_private_rsa_params( GNUTLS_KEY key, gnutls_datum cert) +static int _gnutls_get_private_rsa_params(GNUTLS_KEY key, + gnutls_private_key pkey) { - int ret = 0, result; - opaque str[5*1024]; - int len = sizeof(str); - if (create_structure("rsakey", "PKCS-1.RSAPrivateKey")!=ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_ERROR; - } - - result = get_der("rsakey", cert.data, cert.size); - if (result != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } + key->u = gcry_mpi_copy(pkey.params[0]); + key->A = gcry_mpi_copy(pkey.params[1]); - len = sizeof(str); - result = - read_value("rsakey.privateExponent", str, &len); - if (result != ASN_OK) { - gnutls_assert(); - delete_structure("rsakey"); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - if (gcry_mpi_scan(&key->u, - GCRYMPI_FMT_USG, str, &len) != 0) { - gnutls_assert(); - delete_structure("rsakey"); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - - len = sizeof(str); - result = - read_value("rsakey.modulus", str, &len); - if (result != ASN_OK) { - gnutls_assert(); - delete_structure("rsakey"); - _gnutls_mpi_release(&key->u); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - if (gcry_mpi_scan(&key->A, - GCRYMPI_FMT_USG, str, &len) != 0) { - gnutls_assert(); - delete_structure("rsakey"); - _gnutls_mpi_release(&key->u); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - delete_structure("rsakey"); - - return ret; + return 0; } @@ -251,18 +218,18 @@ int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data) { const X509PKI_SERVER_CREDENTIALS *cred; int ret, i, pdatasize; - opaque* pdata; - gnutls_cert* apr_cert_list; - gnutls_datum apr_pkey; + opaque *pdata; + gnutls_cert *apr_cert_list; + gnutls_private_key apr_pkey; int apr_cert_list_length; - + cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL); if (cred == NULL) { gnutls_assert(); return GNUTLS_E_INSUFICIENT_CRED; } - if (cred->ncerts==0) { + if (cred->ncerts == 0) { gnutls_assert(); return GNUTLS_E_INSUFICIENT_CRED; } @@ -274,33 +241,32 @@ int gen_rsa_certificate(GNUTLS_KEY key, opaque ** data) apr_pkey = cred->pkey[0]; ret = 3; - for (i=0;iversion.major, key->version.minor)) == 0 ) { + if (_gnutls_version_ssl3 + (_gnutls_version_get(key->version.major, key->version.minor)) + == 0) { /* SSL 3.0 */ ciphertext.data = data; ciphertext.size = data_size; - } else { /* TLS 1 */ + } else { /* TLS 1 */ ciphertext.data = &data[2]; dsize = READuint16(data); ciphertext.size = GMIN(dsize, data_size); } - ret = _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, key->u, key->A); + ret = + _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, key->u, + key->A); - if ( ret < 0) { + if (ret < 0) { /* in case decryption fails then don't inform * the peer. Just use a random key. (in order to avoid * attack against pkcs-1 formating). @@ -341,15 +312,17 @@ int proc_rsa_client_kx( GNUTLS_KEY key, opaque* data, int data_size) { RANDOMIZE_KEY(key->key, secure_malloc); } else { ret = 0; - if (plaintext.size != TLS_MASTER_SIZE) { /* WOW */ + if (plaintext.size != TLS_MASTER_SIZE) { /* WOW */ RANDOMIZE_KEY(key->key, secure_malloc); } else { - if (key->version.major != plaintext.data[0]) ret = GNUTLS_E_DECRYPTION_FAILED; - if (key->version.minor != plaintext.data[1]) ret = GNUTLS_E_DECRYPTION_FAILED; + if (key->version.major != plaintext.data[0]) + ret = GNUTLS_E_DECRYPTION_FAILED; + if (key->version.minor != plaintext.data[1]) + ret = GNUTLS_E_DECRYPTION_FAILED; if (ret != 0) { - _gnutls_mpi_release( &key->B); - _gnutls_mpi_release( &key->u); - _gnutls_mpi_release( &key->A); + _gnutls_mpi_release(&key->B); + _gnutls_mpi_release(&key->u); + _gnutls_mpi_release(&key->A); gnutls_assert(); return ret; } @@ -358,87 +331,93 @@ int proc_rsa_client_kx( GNUTLS_KEY key, opaque* data, int data_size) { } } - _gnutls_mpi_release( &key->A); - _gnutls_mpi_release( &key->B); - _gnutls_mpi_release( &key->u); + _gnutls_mpi_release(&key->A); + _gnutls_mpi_release(&key->B); + _gnutls_mpi_release(&key->u); return 0; } -int proc_rsa_certificate( GNUTLS_KEY key, opaque* data, int data_size) { -int size, len; -opaque* p = data; -X509PKI_AUTH_INFO* info; -int dsize = data_size; -int i, j; +int proc_rsa_certificate(GNUTLS_KEY key, opaque * data, int data_size) +{ + int size, len; + opaque *p = data; + X509PKI_AUTH_INFO *info; + int dsize = data_size; + int i, j; key->auth_info = gnutls_calloc(1, sizeof(X509PKI_AUTH_INFO)); - if (key->auth_info==NULL) { + if (key->auth_info == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } key->auth_info_size = sizeof(X509PKI_AUTH_INFO); - - DECR_LEN( dsize, 3); - size = READuint24( p); - p+=3; - if (size==0) { + DECR_LEN(dsize, 3); + size = READuint24(p); + p += 3; + + if (size == 0) { gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } - + info = key->auth_info; i = dsize; - - len=READuint24(p); p+=3; - for(; i > 0; len=READuint24(p),p+=3) { - DECR_LEN(dsize, (len+3)); + len = READuint24(p); + p += 3; + + for (; i > 0; len = READuint24(p), p += 3) { + DECR_LEN(dsize, (len + 3)); info->peer_certificate_list_size++; - p+=len; - i-=len+3; + p += len; + i -= len + 3; } - if (info->peer_certificate_list_size==0) { + if (info->peer_certificate_list_size == 0) { gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } - + dsize = data_size; - i = dsize; - info->peer_certificate_list = gnutls_malloc(sizeof(gnutls_datum)*(info->peer_certificate_list_size)); - if (info->peer_certificate_list==NULL) { + i = dsize; + info->peer_certificate_list = + gnutls_malloc(sizeof(gnutls_datum) * + (info->peer_certificate_list_size)); + if (info->peer_certificate_list == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } - - p = data+3; + + p = data + 3; i = data_size - 3; j = 0; - - len=READuint24(p); p+=3; - for(; i > 0; len=READuint24(p), p+=3) { - if ( j >= info->peer_certificate_list_size) break; + + len = READuint24(p); + p += 3; + for (; i > 0; len = READuint24(p), p += 3) { + if (j >= info->peer_certificate_list_size) + break; info->peer_certificate_list[j].size = len; info->peer_certificate_list[j].data = gnutls_malloc(len); - if (info->peer_certificate_list[j].data==NULL) { + if (info->peer_certificate_list[j].data == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } - - memcpy( info->peer_certificate_list[j].data, p, len); - p+=len; - i-=len+3; + + memcpy(info->peer_certificate_list[j].data, p, len); + p += len; + i -= len + 3; j++; } - - + + #warning "WE DO NOT VERIFY RSA CERTIFICATES" /* FIXME: Verify certificate */ info->peer_certificate_status = GNUTLS_NOT_VERIFIED; - + return 0; } @@ -448,7 +427,7 @@ int gen_rsa_client_kx(GNUTLS_KEY key, opaque ** data) { X509PKI_AUTH_INFO *auth = key->auth_info; svoid *rand; - gnutls_datum sdata; /* data to send */ + gnutls_datum sdata; /* data to send */ MPI pkey, n; int ret; @@ -460,20 +439,23 @@ int gen_rsa_client_kx(GNUTLS_KEY key, opaque ** data) return GNUTLS_E_INSUFICIENT_CRED; } - rand = secure_malloc( TLS_MASTER_SIZE); - if (rand==NULL) + rand = secure_malloc(TLS_MASTER_SIZE); + if (rand == NULL) return GNUTLS_E_MEMORY_ERROR; - RANDOMIZE_KEY( key->key, secure_malloc); + RANDOMIZE_KEY(key->key, secure_malloc); key->key.data[0] = key->version.major; key->key.data[1] = key->version.minor; - if ( (ret=_gnutls_get_rsa_params( key, NULL, &n, &pkey, auth->peer_certificate_list[0])) < 0 ) { + if ((ret = + _gnutls_get_rsa_params(key, NULL, &n, &pkey, + auth->peer_certificate_list[0])) < 0) { gnutls_assert(); return ret; } - if ( (ret=_gnutls_pkcs1_rsa_encrypt( &sdata, key->key, pkey, n)) < 0 ) { + if ((ret = + _gnutls_pkcs1_rsa_encrypt(&sdata, key->key, pkey, n)) < 0) { gnutls_assert(); _gnutls_mpi_release(&pkey); _gnutls_mpi_release(&n); @@ -483,18 +465,20 @@ int gen_rsa_client_kx(GNUTLS_KEY key, opaque ** data) _gnutls_mpi_release(&pkey); _gnutls_mpi_release(&n); - if ( _gnutls_version_ssl3(_gnutls_version_get(key->version.major, key->version.minor)) == 0 ) { + if (_gnutls_version_ssl3 + (_gnutls_version_get(key->version.major, key->version.minor)) + == 0) { /* SSL 3.0 */ *data = sdata.data; return sdata.size; - } else { /* TLS 1 */ - *data = gnutls_malloc(sdata.size+2); - if (*data==NULL) { + } else { /* TLS 1 */ + *data = gnutls_malloc(sdata.size + 2); + if (*data == NULL) { gnutls_free_datum(&sdata); - return GNUTLS_E_MEMORY_ERROR; + return GNUTLS_E_MEMORY_ERROR; } - WRITEuint16( sdata.size, *data); - memcpy( &(*data)[2], sdata.data, sdata.size); + WRITEuint16(sdata.size, *data); + memcpy(&(*data)[2], sdata.data, sdata.size); ret = sdata.size + 2; gnutls_free_datum(&sdata); return ret; diff --git a/lib/auth_x509.h b/lib/auth_x509.h index d5c4855ded..fba3cc5a54 100644 --- a/lib/auth_x509.h +++ b/lib/auth_x509.h @@ -23,7 +23,7 @@ typedef struct { */ /* FIXME: replace datum with an internal type */ - gnutls_datum * pkey; /* private keys. It contains ncerts private + gnutls_private_key * pkey; /* private keys. It contains ncerts private * keys. pkey[i] corresponds to certificate in * cert_list[i][0]. */ diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in index 07cd7becaf..1757587b9a 100644 --- a/lib/gnutls.h.in +++ b/lib/gnutls.h.in @@ -55,9 +55,10 @@ typedef enum PKAlgorithm { GNUTLS_PK_RSA = 1, GNUTLS_PK_DSA, /* sign only */ GNUTLS_PK_DH } PKAlgorithm; -/* You cannot use this structure directly +/* You cannot use these structures directly */ typedef struct gnutls_cert gnutls_cert; +typedef struct gnutls_private_key gnutls_private_key; /* internal functions */ @@ -179,7 +180,7 @@ typedef struct { */ int ncerts; /* contains the number of columns in cert_list. */ - gnutls_datum * pkey; /* private keys. It contains ncerts private + gnutls_private_key * pkey; /* private keys. It contains ncerts private * keys. */ } X509PKI_SERVER_CREDENTIALS; diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 5f7437844e..8133d3f228 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -111,7 +111,10 @@ int i,j; gnutls_free( sc.cert_list[i]); } gnutls_free( sc.cert_list ); - gnutls_free_datum( sc.pkey); + for (i=0;ipkey == NULL) return GNUTLS_E_MEMORY_ERROR; - res->pkey[0].data = b64; - res->pkey[0].size = siz; + tmp.data = b64; + tmp.size = siz; + if ( (ret =_gnutls_pkcs1key2gnutlsKey(&res->pkey[0], tmp)) < 0) { + gnutls_assert(); + return ret; + } - fclose(fd2); return 0; } @@ -512,3 +520,92 @@ gnutls_cert *_gnutls_find_cert(gnutls_cert ** cert_list, } return cert; } +/* Converts an RSA PKCS#1 key to + * an internal structure (gnutls_private_key) + */ +int _gnutls_pkcs1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum cert) { + int ret = 0, result; + opaque str[5*1024]; + int len = sizeof(str); + + pkey->pk_algorithm = GNUTLS_PK_RSA; + + /* we do return 2 MPIs + */ + pkey->params = gnutls_malloc(2*sizeof(MPI)); + + if (create_structure("rsakey", "PKCS-1.RSAPrivateKey")!=ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_ERROR; + } + + result = get_der("rsakey", cert.data, cert.size); + if (result != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + len = sizeof(str); + result = + read_value("rsakey.privateExponent", str, &len); + if (result != ASN_OK) { + gnutls_assert(); + delete_structure("rsakey"); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + if (gcry_mpi_scan(&pkey->params[0], /* u */ + GCRYMPI_FMT_USG, str, &len) != 0) { + gnutls_assert(); + delete_structure("rsakey"); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + + len = sizeof(str); + result = + read_value("rsakey.modulus", str, &len); + if (result != ASN_OK) { + gnutls_assert(); + delete_structure("rsakey"); + _gnutls_mpi_release(&pkey->params[0]); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + if (gcry_mpi_scan(&pkey->params[1], /* A */ + GCRYMPI_FMT_USG, str, &len) != 0) { + gnutls_assert(); + delete_structure("rsakey"); + _gnutls_mpi_release(&pkey->params[0]); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + delete_structure("rsakey"); + + if (gnutls_set_datum( &pkey->raw, cert.data, cert.size) < 0) { + _gnutls_mpi_release(&pkey->params[0]); + _gnutls_mpi_release(&pkey->params[1]); + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + return ret; + + +} + +void _gnutls_free_private_key( gnutls_private_key pkey) { +int n, i; + + switch( pkey.pk_algorithm) { + case GNUTLS_PK_RSA: + n = 2;/* the number of parameters in MPI* */ + break; + default: + n=0; + } + for (i=0;i