diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2004-04-03 10:24:32 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2004-04-03 10:24:32 +0000 |
commit | 94d12616e8d5d5b73f40b735099fb61f083b30a2 (patch) | |
tree | 7110408cdb7b7e1d34f5316267110657e57c1fce /lib | |
parent | 1635a2cb0f60124047a75b77c52fc9f2bf7fc291 (diff) | |
download | gnutls-94d12616e8d5d5b73f40b735099fb61f083b30a2.tar.gz |
*** empty log message ***
Diffstat (limited to 'lib')
-rw-r--r-- | lib/auth_cert.c | 48 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 77 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 2 |
3 files changed, 71 insertions, 56 deletions
diff --git a/lib/auth_cert.c b/lib/auth_cert.c index e54051254f..c0de1ed568 100644 --- a/lib/auth_cert.c +++ b/lib/auth_cert.c @@ -123,9 +123,55 @@ static int _gnutls_check_pk_algo_in_list(const gnutls_pk_algorithm *pk_algos, } +/* Returns the issuer's Distinguished name in odn, of the certificate + * specified in cert. + */ +static int _gnutls_cert_get_issuer_dn(gnutls_cert * cert, gnutls_datum * odn) +{ + ASN1_TYPE dn; + int len, result; + int start, end; + + if ((result=asn1_create_element + (_gnutls_get_pkix(), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + result = asn1_der_decoding(&dn, cert->raw.data, cert->raw.size, NULL); + if (result != ASN1_SUCCESS) { + /* couldn't decode DER */ + gnutls_assert(); + asn1_delete_structure(&dn); + return _gnutls_asn2err(result); + } + + result = asn1_der_decoding_startEnd(dn, cert->raw.data, cert->raw.size, + "tbsCertificate.issuer", &start, + &end); + + if (result != ASN1_SUCCESS) { + /* couldn't decode DER */ + gnutls_assert(); + asn1_delete_structure(&dn); + return _gnutls_asn2err(result); + } + asn1_delete_structure(&dn); + + len = end - start + 1; + + odn->size = len; + odn->data = &cert->raw.data[start]; + + return 0; +} + /* Locates the most appropriate x509 certificate using the * given DN. If indx == -1 then no certificate was found. + * + * That is to guess which certificate to use, based on the + * CAs and sign algorithms supported by the peer server. */ static int _find_x509_cert(const gnutls_certificate_credentials cred, opaque * _data, size_t _data_size, @@ -151,7 +197,7 @@ static int _find_x509_cert(const gnutls_certificate_credentials cred, for (i = 0; i < cred->ncerts; i++) { for (j = 0; j < cred->cert_list_length[i]; j++) { if ((result = - _gnutls_cert_get_dn(&cred-> + _gnutls_cert_get_issuer_dn(&cred-> cert_list[i][j], &odn)) < 0) { gnutls_assert(); diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index b611a9b9a5..3c78a21056 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -637,27 +637,40 @@ int _gnutls_x509_crt_to_gcert(gnutls_cert * gcert, gnutls_x509_crt cert, gcert->cert_type = GNUTLS_CRT_X509; if ( !(flags & CERT_NO_COPY)) { + #define SMALL_DER 512 opaque* der; - size_t der_size = 0; - - ret = gnutls_x509_crt_export( cert, GNUTLS_X509_FMT_DER, NULL, &der_size); - if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { - gnutls_assert(); - return ret; - } - - der = gnutls_malloc( der_size); + size_t der_size = SMALL_DER; + + /* initially allocate a bogus size, just in case the certificate + * fits in it. That way we minimize the DER encodings performed. + */ + der = gnutls_malloc( SMALL_DER); if (der == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } - + ret = gnutls_x509_crt_export( cert, GNUTLS_X509_FMT_DER, der, &der_size); - if (ret < 0) { + if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { gnutls_assert(); gnutls_free(der); return ret; } + + if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { + der = gnutls_realloc( der, der_size); + if (der == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + ret = gnutls_x509_crt_export( cert, GNUTLS_X509_FMT_DER, der, &der_size); + if (ret < 0) { + gnutls_assert(); + gnutls_free(der); + return ret; + } + } gcert->raw.data = der; gcert->raw.size = der_size; @@ -698,45 +711,3 @@ void _gnutls_gcert_deinit(gnutls_cert *cert) _gnutls_free_datum(&cert->raw); } -/* Returns the issuer's Distinguished name in odn, of the certificate - * specified in cert. - */ -int _gnutls_cert_get_dn(gnutls_cert * cert, gnutls_datum * odn ) -{ - ASN1_TYPE dn; - int len, result; - int start, end; - - if ((result=asn1_create_element - (_gnutls_get_pkix(), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS) { - gnutls_assert(); - return _gnutls_asn2err(result); - } - - result = asn1_der_decoding(&dn, cert->raw.data, cert->raw.size, NULL); - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - gnutls_assert(); - asn1_delete_structure(&dn); - return _gnutls_asn2err(result); - } - - result = asn1_der_decoding_startEnd(dn, cert->raw.data, cert->raw.size, - "tbsCertificate.issuer", &start, - &end); - - if (result != ASN1_SUCCESS) { - /* couldn't decode DER */ - gnutls_assert(); - asn1_delete_structure(&dn); - return _gnutls_asn2err(result); - } - asn1_delete_structure(&dn); - - len = end - start + 1; - - odn->size = len; - odn->data = &cert->raw.data[start]; - - return 0; -} diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index c1384f17b3..803eca5033 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -86,8 +86,6 @@ int _gnutls_x509_raw_cert_to_gcert(gnutls_cert * gcert, const gnutls_datum *derC int _gnutls_x509_crt_to_gcert(gnutls_cert * gcert, gnutls_x509_crt cert, unsigned int flags); -int _gnutls_cert_get_dn(gnutls_cert * cert, gnutls_datum * odn); - void _gnutls_gkey_deinit(gnutls_privkey *key); void _gnutls_gcert_deinit(gnutls_cert *cert); |