summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2004-04-03 10:24:32 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2004-04-03 10:24:32 +0000
commit94d12616e8d5d5b73f40b735099fb61f083b30a2 (patch)
tree7110408cdb7b7e1d34f5316267110657e57c1fce /lib
parent1635a2cb0f60124047a75b77c52fc9f2bf7fc291 (diff)
downloadgnutls-94d12616e8d5d5b73f40b735099fb61f083b30a2.tar.gz
*** empty log message ***
Diffstat (limited to 'lib')
-rw-r--r--lib/auth_cert.c48
-rw-r--r--lib/gnutls_cert.c77
-rw-r--r--lib/gnutls_cert.h2
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);