From: Nikos Mavrogiannopoulos Date: Wed, 10 Oct 2012 18:11:28 +0000 (+0200) Subject: Bug fixes in the openssl encrypted PEM key parsing. X-Git-Tag: gnutls_3_1_3~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f16ef39ef0303b02d7fa590a37820440c466ce8d;p=thirdparty%2Fgnutls.git Bug fixes in the openssl encrypted PEM key parsing. --- diff --git a/lib/x509/privkey_openssl.c b/lib/x509/privkey_openssl.c index 6ef1410caa..1c055ad97a 100644 --- a/lib/x509/privkey_openssl.c +++ b/lib/x509/privkey_openssl.c @@ -66,11 +66,17 @@ openssl_hash_password (const char *pass, gnutls_datum_t * key, gnutls_datum_t * { err = gnutls_hash (hash, pass, strlen (pass)); if (err) - goto hash_err; + { + gnutls_assert(); + goto hash_err; + } } err = gnutls_hash (hash, salt->data, 8); if (err) - goto hash_err; + { + gnutls_assert(); + goto hash_err; + } gnutls_hash_deinit (hash, md5); @@ -131,7 +137,7 @@ gnutls_x509_privkey_import_openssl (gnutls_x509_privkey_t key, const char *pem_header = (void*)data->data; const char *pem_header_start = (void*)data->data; ssize_t pem_header_size; - int ret, err; + int ret; unsigned int i, iv_size, l; pem_header_size = data->size; @@ -178,7 +184,7 @@ gnutls_x509_privkey_import_openssl (gnutls_x509_privkey_t key, salt.size = iv_size; salt.data = gnutls_malloc (salt.size); if (!salt.data) - return GNUTLS_E_MEMORY_ERROR; + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); for (i = 0; i < salt.size * 2; i++) { @@ -231,35 +237,43 @@ gnutls_x509_privkey_import_openssl (gnutls_x509_privkey_t key, enc_key.size = gnutls_cipher_get_key_size (cipher); enc_key.data = gnutls_malloc (enc_key.size); if (!enc_key.data) - goto out_b64; + { + ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + goto out_b64; + } key_data = gnutls_malloc (b64_data.size); if (!key_data) - goto out_enc_key; + { + ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + goto out_enc_key; + } while (1) { memcpy (key_data, b64_data.data, b64_data.size); ret = openssl_hash_password (password, &enc_key, &salt); - if (ret) - goto out; + if (ret < 0) + { + gnutls_assert(); + goto out; + } - err = gnutls_cipher_init (&handle, cipher, &enc_key, &salt); - if (err) + ret = gnutls_cipher_init (&handle, cipher, &enc_key, &salt); + if (ret < 0) { gnutls_assert(); gnutls_cipher_deinit (handle); - ret = err; goto out; } - err = gnutls_cipher_decrypt (handle, key_data, b64_data.size); + ret = gnutls_cipher_decrypt (handle, key_data, b64_data.size); gnutls_cipher_deinit (handle); - if (err) + + if (ret < 0) { gnutls_assert(); - ret = -err; goto out; } @@ -278,7 +292,10 @@ gnutls_x509_privkey_import_openssl (gnutls_x509_privkey_t key, keylen = 0; if (lenlen > 3) - goto fail; + { + gnutls_assert(); + goto fail; + } while (lenlen) { @@ -290,28 +307,31 @@ gnutls_x509_privkey_import_openssl (gnutls_x509_privkey_t key, keylen += ofs; /* If there appears to be more padding than required, fail */ - if (b64_data.size - keylen >= blocksize) - goto fail; + if (b64_data.size - keylen > blocksize) + { + gnutls_assert(); + goto fail; + } /* If the padding bytes aren't all equal to the amount of padding, fail */ ofs = keylen; while (ofs < b64_data.size) { if (key_data[ofs] != b64_data.size - keylen) - goto fail; + { + gnutls_assert(); + goto fail; + } ofs++; } key_datum.data = key_data; key_datum.size = keylen; - err = + ret = gnutls_x509_privkey_import (key, &key_datum, GNUTLS_X509_FMT_DER); - if (!err) - { - ret = 0; - goto out; - } + if (ret == 0) + goto out; } fail: ret = GNUTLS_E_DECRYPTION_FAILED; diff --git a/tests/Makefile.am b/tests/Makefile.am index d0061c14b8..b6c14bead6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -70,7 +70,7 @@ ctests = mini-deflate simple gc set_pkcs12_cred certder certuniqueid \ mini-loss-time mini-tdb mini-dtls-rehandshake mini-record \ mini-termination mini-x509-cas mini-x509-2 pkcs12_simple \ mini-emsgsize-dtls mini-handshake-timeout chainverify-unsorted \ - mini-dtls-heartbeat mini-x509-callbacks + mini-dtls-heartbeat mini-x509-callbacks key-openssl if ENABLE_OCSP ctests += ocsp diff --git a/tests/key-openssl.c b/tests/key-openssl.c new file mode 100644 index 0000000000..9d2ef9d460 --- /dev/null +++ b/tests/key-openssl.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2008-2012 Free Software Foundation, Inc. + * + * Author: David Marín Carreño + * + * This file is part of GnuTLS. + * + * GnuTLS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GnuTLS; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "utils.h" + +static void +tls_log_func (int level, const char *str) +{ + fprintf (stderr, "%s |<%d>| %s", "crq_key_id", level, str); +} + +const char key1[] = +"-----BEGIN RSA PRIVATE KEY-----\n" +"Proc-Type: 4,ENCRYPTED\n" +"DEK-Info: DES-EDE3-CBC,82B2F7684A1713F8\n" +"\n" +"1zzOuu89dfFc2UkFCtSJBsBeEFxV8wE84OSxoWu4aYkPhl1LR08BchaTbjeLTP0b\n" +"t961vVpva0ekJkwGDEgmqlGjmhJq9y2sJfq7IeYa8OdTilfGrG1xeJ1QGBi6SCfR\n" +"s/PhkMxwGBtrZ2Z7bEcLT5dQKmKRqsthnClQggmngvk7zX7bPk0hKQKvf+FDxt6x\n" +"hzEaF3k9juU6vAVVSakrZ4QDqk9MUuTGHx0ksTDcC4EESS0l3Ybuum/rAzR4lQKR\n" +"4OLmAeYBDl+l/PSMllfd5x/z1YXYoiAbkpT4ix0lyZJgHrvrYIeUtJk2ODiMHezL\n" +"9BbK7EobtOGmrDLUNVX5BpdaExkWMGkioqzs2QqD/VkKu8RcNSsHVGqkdWKuhzXo\n" +"wcczQ+RiHckN2uy/zApubEWZNLPeDQ499kaF+QdZ+h4RM6E1r1Gu+A==\n" +"-----END RSA PRIVATE KEY-----\n"; + +const char key2[] = +"-----BEGIN RSA PRIVATE KEY-----\n" +"Proc-Type: 4,ENCRYPTED\n" +"DEK-Info: AES-128-CBC,2A57FF97B701B3F760145D7446929481\n" +"\n" +"mGAPhSw48wZBnkHOhfMDg8yL2IBgMuTmeKE4xoHi7T6isHBNfkqMd0iJ+DJP/OKb\n" +"t+7lkKjj/xQ7w/bOBvBxlfRe4MW6+ejCdAFD9XSolW6WN6CEJPMI4UtmOK5inqcC\n" +"8l2l54f/VGrVN9uavU3KlXCjrd3Jp9B0Mu4Zh/UU4+EWs9rJAZfLIn+vHZ3OHetx\n" +"g74LdV7nC7lt/fjxc1caNIfgHs40dUt9FVrnJvAtkcNMtcjX/D+L8ZrLgQzIWFcs\n" +"WAbUZj7Me22mCli3RPET7Je37K59IzfWgbWFCGaNu3X02g5xtCfdcn/Uqy9eofH0\n" +"YjKRhpgXPeGJCkoRqDeUHQNPpVP5HrzDZMVK3E4DC03C8qvgsYvuwYt3KkbG2fuA\n" +"F3bDyqlxSOm7uxF/K3YzI44v8/D8GGnLBTpN+ANBdiY=\n" +"-----END RSA PRIVATE KEY-----\n"; + +void +doit (void) +{ + gnutls_x509_privkey_t pkey; + int ret; + gnutls_datum_t key; + + ret = gnutls_global_init (); + if (ret < 0) + fail ("gnutls_global_init: %d\n", ret); + + gnutls_global_set_log_function (tls_log_func); + if (debug) + gnutls_global_set_log_level (4711); + + ret = gnutls_x509_privkey_init (&pkey); + if (ret < 0) + fail ("gnutls_x509_privkey_init: %d\n", ret); + + key.data = (void*)key1; + key.size = sizeof(key1); + ret = gnutls_x509_privkey_import_openssl (pkey, &key, "123456"); + if (ret < 0) + { + fail ("gnutls_x509_privkey_import_openssl (key1): %s\n", gnutls_strerror(ret)) ; + } + gnutls_x509_privkey_deinit (pkey); + + ret = gnutls_x509_privkey_init (&pkey); + if (ret < 0) + fail ("gnutls_x509_privkey_init: %d\n", ret); + + key.data = (void*)key2; + key.size = sizeof(key2); + ret = gnutls_x509_privkey_import_openssl (pkey, &key, "a123456"); + if (ret < 0) + { + fail ("gnutls_x509_privkey_import_openssl (key2): %s\n", gnutls_strerror(ret)) ; + } + gnutls_x509_privkey_deinit (pkey); + + + gnutls_global_deinit (); +}