summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2015-06-25 15:08:54 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2015-06-25 15:10:06 +0200
commit0debaca946b74c66e67ed1a86c671ec3573b779a (patch)
tree387c179069431e6ad630a12b75a0e30d4bb943c5
parent187283be4a68652b7878faad418be3be6cbd3430 (diff)
downloadgnutls-0debaca946b74c66e67ed1a86c671ec3573b779a.tar.gz
gnutls_x509_privkey_import: optimized private key loading
-rw-r--r--lib/x509/privkey.c52
1 files changed, 28 insertions, 24 deletions
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index dd791157db..f0130e39ef 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -470,33 +470,37 @@ gnutls_x509_privkey_import(gnutls_x509_privkey_t key,
/* If the Certificate is in PEM format then decode it
*/
if (format == GNUTLS_X509_FMT_PEM) {
- /* Try the first header */
- result =
- _gnutls_fbase64_decode(PEM_KEY_RSA, data->data,
- data->size, &_data);
-
- if (result >= 0)
- key->pk_algorithm = GNUTLS_PK_RSA;
+ unsigned size;
+ char *ptr = memmem(data->data, data->size, "-----BEGIN ", sizeof("-----BEGIN ")-1);
- if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) {
- /* try for the second header */
- result =
- _gnutls_fbase64_decode(PEM_KEY_DSA, data->data,
- data->size, &_data);
+ result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
- if (result >= 0)
- key->pk_algorithm = GNUTLS_PK_DSA;
+ if (ptr != NULL) {
+ ptr += sizeof("-----BEGIN ")-1;
+ size = data->size - ((ptrdiff_t)ptr - (ptrdiff_t)data->data);
- if (result ==
- GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) {
- /* try for the second header */
- result =
- _gnutls_fbase64_decode(PEM_KEY_ECC,
- data->data,
- data->size,
- &_data);
- if (result >= 0)
- key->pk_algorithm = GNUTLS_PK_EC;
+ if (size > sizeof(PEM_KEY_RSA)) {
+ if (memcmp(ptr, PEM_KEY_RSA, sizeof(PEM_KEY_RSA)-1) == 0) {
+ result =
+ _gnutls_fbase64_decode(PEM_KEY_RSA, data->data,
+ data->size, &_data);
+ if (result >= 0)
+ key->pk_algorithm = GNUTLS_PK_RSA;
+ } else if (memcmp(ptr, PEM_KEY_ECC, sizeof(PEM_KEY_ECC)-1) == 0) {
+ result =
+ _gnutls_fbase64_decode(PEM_KEY_ECC,
+ data->data,
+ data->size,
+ &_data);
+ if (result >= 0)
+ key->pk_algorithm = GNUTLS_PK_EC;
+ } else if (memcmp(ptr, PEM_KEY_DSA, sizeof(PEM_KEY_DSA)-1) == 0) {
+ result =
+ _gnutls_fbase64_decode(PEM_KEY_DSA, data->data,
+ data->size, &_data);
+ if (result >= 0)
+ key->pk_algorithm = GNUTLS_PK_DSA;
+ }
}
}