All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] pem: Parse PKCS#1 formatted private keys
@ 2020-11-20 20:28 Andrew Zaborowski
  2020-11-20 20:28 ` [PATCH 2/5] pem: Decrypt PKCS#1 encrypted " Andrew Zaborowski
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2020-11-20 20:28 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 5473 bytes --]

The PKCS#1 RSAPrivateKey format is used within the PKCS#8 PrivateKey
structure so we just need to wrap it in some extra ASN.1 data to get a
format understood by the pkcs8-key-parse module.

Improve some comments with the right RFC references.
---
 ell/asn1-private.h |   1 +
 ell/pem.c          | 106 +++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 98 insertions(+), 9 deletions(-)

diff --git a/ell/asn1-private.h b/ell/asn1-private.h
index e34f977..2a31241 100644
--- a/ell/asn1-private.h
+++ b/ell/asn1-private.h
@@ -29,6 +29,7 @@
 #define ASN1_ID_INTEGER		ASN1_ID(ASN1_CLASS_UNIVERSAL, 0, 0x02)
 #define ASN1_ID_BIT_STRING	ASN1_ID(ASN1_CLASS_UNIVERSAL, 0, 0x03)
 #define ASN1_ID_OCTET_STRING	ASN1_ID(ASN1_CLASS_UNIVERSAL, 0, 0x04)
+#define ASN1_ID_NULL		ASN1_ID(ASN1_CLASS_UNIVERSAL, 0, 0x05)
 #define ASN1_ID_OID		ASN1_ID(ASN1_CLASS_UNIVERSAL, 0, 0x06)
 #define ASN1_ID_UTF8STRING	ASN1_ID(ASN1_CLASS_UNIVERSAL, 0, 0x0c)
 #define ASN1_ID_PRINTABLESTRING	ASN1_ID(ASN1_CLASS_UNIVERSAL, 0, 0x13)
diff --git a/ell/pem.c b/ell/pem.c
index b54270e..99020b1 100644
--- a/ell/pem.c
+++ b/ell/pem.c
@@ -400,14 +400,21 @@ static struct l_key *pem_load_private_key(uint8_t *content,
 	struct l_key *pkey = NULL;
 
 	/*
-	 * RFC7469- and PKCS#8-compatible label (default in OpenSSL 1.0.1+)
-	 * and the older (OpenSSL <= 0.9.8 default) label.
+	 * RFC7468 Section 10-compatible unencrypted private key label
+	 * (also mentioned in PKCS#8/RFC5958 Section 5), encodes
+	 * the PKCS#8/RFC5958 PrivateKeyInfo structure -- supported
+	 * directly by the pkcs8-key-parser kernel module.
 	 */
-	if (!strcmp(label, "PRIVATE KEY") ||
-			!strcmp(label, "RSA PRIVATE KEY"))
+	if (!strcmp(label, "PRIVATE KEY"))
 		goto done;
 
-	/* RFC5958 (PKCS#8) section 3 type encrypted key label */
+	/*
+	 * RFC7468 Section 11-compatible encrypted private key label
+	 * (also mentioned in PKCS#8/RFC5958 Section 5), encodes
+	 * the PKCS#8/RFC5958 EncryptedPrivateKeyInfo structure.  We
+	 * decrypt it into a plain PrivateKeyInfo for the
+	 * pkcs8-key-parser module.
+	 */
 	if (!strcmp(label, "ENCRYPTED PRIVATE KEY")) {
 		const uint8_t *key_info, *alg_id, *data;
 		uint8_t tag;
@@ -479,11 +486,92 @@ static struct l_key *pem_load_private_key(uint8_t *content,
 	}
 
 	/*
-	 * TODO: handle RSA PRIVATE KEY format encrypted keys
-	 * (as produced by "openssl rsa" commands), incompatible with
-	 * RFC7468 parsing because of the headers present before
-	 * base64-encoded data.
+	 * Legacy RSA private key label aka. SSLeay format label, created
+	 * by most software but not documented in an RFC.  Encodes the
+	 * PKCS#1/RFC8017 RSAPrivateKey structure.  We wrap it in a PKCS#8
+	 * PrivateKeyInfo for the pkcs8-key-parser module.
+	 *
+	 * TODO: decrypt RSA PRIVATE KEY format encrypted keys
+	 * as produced by "openssl rsa" commands.  These are incompatible
+	 * with RFC7468 parsing because of the RFC822 headers present
+	 * before base64-encoded data.  The format is documented in
+	 * RFC1421 and the encryption algorithms in RFC1423 although
+	 * openssl allows many more algorithms than those documented.
+	 * Then wrap in a PrivateKeyInfo like above.
 	 */
+	if (!strcmp(label, "RSA PRIVATE KEY")) {
+		const uint8_t *data;
+		uint8_t tag;
+		size_t data_len;
+		const uint8_t *key_data;
+		size_t key_data_len;
+		int i;
+		uint8_t *private_key;
+		size_t private_key_len;
+		uint8_t *one_asymmetric_key;
+		uint8_t *ptr;
+
+		static const uint8_t version0[] = {
+			ASN1_ID_INTEGER, 0x01, 0x00
+		};
+		static const uint8_t pkcs1_rsa_encryption[] = {
+			ASN1_ID_SEQUENCE, 0x0d,
+			ASN1_ID_OID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+			0x01, 0x01, 0x01,
+			ASN1_ID_NULL, 0x00,
+		};
+
+		/*
+		 * Sanity check that it's a version 0 or 1 RSAPrivateKey
+		 * structure with the 8 integers, if it's not, make a last
+		 * ditch attempt to load it into the kernel directly.
+		 */
+		key_data = asn1_der_find_elem(content, len, 0, &tag,
+						&key_data_len);
+		if (!key_data || tag != ASN1_ID_SEQUENCE)
+			goto done;
+
+		data = asn1_der_find_elem(key_data, key_data_len, 0, &tag,
+						&data_len);
+		if (!data || tag != ASN1_ID_INTEGER || data_len != 1 ||
+				(data[0] != 0x00 && data[0] != 0x01))
+			goto done;
+
+		for (i = 1; i < 9; i++) {
+			data = asn1_der_find_elem(key_data, key_data_len,
+							i, &tag, &data_len);
+			if (!data || tag != ASN1_ID_INTEGER || data_len < 1)
+				goto done;
+		}
+
+		private_key = l_malloc(10 + len);
+		ptr = private_key;
+		*ptr++ = ASN1_ID_OCTET_STRING;
+		asn1_write_definite_length(&ptr, len);
+		memcpy(ptr, content, len);
+		ptr += len;
+		private_key_len = ptr - private_key;
+
+		one_asymmetric_key = l_malloc(32 + private_key_len);
+		ptr = one_asymmetric_key;
+		*ptr++ = ASN1_ID_SEQUENCE;
+		asn1_write_definite_length(&ptr,
+						sizeof(version0) +
+						sizeof(pkcs1_rsa_encryption) +
+						private_key_len);
+		memcpy(ptr, version0, sizeof(version0));
+		ptr += sizeof(version0);
+		memcpy(ptr, pkcs1_rsa_encryption, sizeof(pkcs1_rsa_encryption));
+		ptr += sizeof(pkcs1_rsa_encryption);
+		memcpy(ptr, private_key, private_key_len);
+		ptr += private_key_len;
+		l_free(private_key);
+
+		l_free(content);
+		content = one_asymmetric_key;
+		len = ptr - one_asymmetric_key;
+		goto done;
+	}
 
 	/* Label not known */
 	goto err;
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/5] pem: Decrypt PKCS#1 encrypted private keys
  2020-11-20 20:28 [PATCH 1/5] pem: Parse PKCS#1 formatted private keys Andrew Zaborowski
@ 2020-11-20 20:28 ` Andrew Zaborowski
  2020-11-20 20:28 ` [PATCH 3/5] examples: More error messages in https-{client, server}-test Andrew Zaborowski
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2020-11-20 20:28 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 12044 bytes --]

---
 ell/pem.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 283 insertions(+), 22 deletions(-)

diff --git a/ell/pem.c b/ell/pem.c
index 99020b1..0d25a07 100644
--- a/ell/pem.c
+++ b/ell/pem.c
@@ -31,6 +31,7 @@
 #include <unistd.h>
 #include <sys/mman.h>
 #include <strings.h>
+#include <ctype.h>
 
 #include "util.h"
 #include "private.h"
@@ -194,7 +195,8 @@ const char *pem_next(const void *buf, size_t buf_len, char **type_label,
 }
 
 static uint8_t *pem_load_buffer(const void *buf, size_t buf_len,
-				char **type_label, size_t *len)
+				char **out_type_label, size_t *out_len,
+				char **out_headers)
 {
 	size_t base64_len;
 	const char *base64;
@@ -206,9 +208,50 @@ static uint8_t *pem_load_buffer(const void *buf, size_t buf_len,
 	if (!base64)
 		return NULL;
 
-	ret = l_base64_decode(base64, base64_len, len);
+	if (memchr(base64, ':', base64_len)) {
+		const char *start;
+		const char *end;
+
+		while (base64_len && isspace(*base64)) {
+			base64++;
+			base64_len--;
+		}
+
+		start = base64;
+
+		if (!(end = memmem(start, base64_len, "\n\n", 2)) &&
+				!(end = memmem(start, base64_len, "\n\r\n", 3)))
+			return NULL;
+
+		/* Check that each header line has a key and a colon */
+		while (start < end) {
+			const char *lf = rawmemchr(start, '\n');
+			const char *colon = memchr(start, ':', lf - start);
+
+			if (!colon)
+				return NULL;
+
+			for (; start < colon; start++)
+				if (isalnum(*start))
+					break;
+
+			if (start == colon)
+				return NULL;
+
+			start = lf + 1;
+		}
+
+		if (out_headers)
+			*out_headers = l_strndup(base64, end - base64);
+
+		base64_len -= end + 2 - base64;
+		base64 = end + 2;
+	} else if (out_headers)
+		*out_headers = NULL;
+
+	ret = l_base64_decode(base64, base64_len, out_len);
 	if (ret) {
-		*type_label = label;
+		*out_type_label = label;
 		return ret;
 	}
 
@@ -220,7 +263,7 @@ static uint8_t *pem_load_buffer(const void *buf, size_t buf_len,
 LIB_EXPORT uint8_t *l_pem_load_buffer(const void *buf, size_t buf_len,
 					char **type_label, size_t *out_len)
 {
-	return pem_load_buffer(buf, buf_len, type_label, out_len);
+	return pem_load_buffer(buf, buf_len, type_label, out_len, NULL);
 }
 
 struct pem_file_info {
@@ -260,8 +303,8 @@ static void pem_file_close(struct pem_file_info *info)
 	close(info->fd);
 }
 
-LIB_EXPORT uint8_t *l_pem_load_file(const char *filename,
-					char **type_label, size_t *len)
+static uint8_t *pem_load_file(const char *filename, char **out_type_label,
+				size_t *out_len, char **out_headers)
 {
 	struct pem_file_info file;
 	uint8_t *result;
@@ -273,11 +316,17 @@ LIB_EXPORT uint8_t *l_pem_load_file(const char *filename,
 		return NULL;
 
 	result = pem_load_buffer(file.data, file.st.st_size,
-					type_label, len);
+					out_type_label, out_len, out_headers);
 	pem_file_close(&file);
 	return result;
 }
 
+LIB_EXPORT uint8_t *l_pem_load_file(const char *filename,
+					char **out_type_label, size_t *out_len)
+{
+	return pem_load_file(filename, out_type_label, out_len, NULL);
+}
+
 static struct l_certchain *pem_list_to_chain(struct l_queue *list)
 {
 	struct l_certchain *chain;
@@ -391,10 +440,166 @@ LIB_EXPORT struct l_queue *l_pem_load_certificate_list(const char *filename)
 	return list;
 }
 
+#define SKIP_WHITESPACE(str)	\
+	while (isspace(*(str)))	\
+		(str)++;
+
+static const char *parse_rfc1421_dek_info(char *headers,
+						const char **out_params)
+{
+	const char *proc_type = NULL;
+	char *dek_info = NULL;
+	char *comma;
+
+	while (headers) {
+		char *lf = strchrnul(headers, '\n');
+		char *key;
+
+		key = headers;
+		SKIP_WHITESPACE(key);
+		headers = (*lf == '\n') ? lf + 1 : NULL;
+
+		if (!memcmp(key, "X-", 2))
+			key += 2;
+
+		if (!memcmp(key, "Proc-Type:", 10)) {
+			if (proc_type)
+				return NULL;
+
+			proc_type = key + 10;
+			SKIP_WHITESPACE(proc_type);
+		} else if (!memcmp(key, "DEK-Info:", 9)) {
+			if (dek_info)
+				return NULL;
+
+			dek_info = key + 10;
+			SKIP_WHITESPACE(dek_info);
+		} else
+			continue;
+
+		while (isspace(lf[-1]))
+			lf--;
+
+		*lf = '\0';
+	}
+
+	if (!proc_type || !dek_info)
+		return NULL;
+
+	/* Skip the version field (should be 3 or 4) */
+	proc_type = strchr(proc_type, ',');
+	if (!proc_type)
+		return NULL;
+
+	proc_type++;
+	SKIP_WHITESPACE(proc_type);
+
+	/* Section 4.6.1.1 */
+	if (strcmp(proc_type, "ENCRYPTED"))
+		return NULL;
+
+	comma = strchr(dek_info, ',');
+	if (comma) {
+		*out_params = comma + 1;
+		SKIP_WHITESPACE(*out_params);
+
+		while (comma > dek_info && isspace(comma[-1]))
+			comma--;
+
+		*comma = '\0';
+	}
+
+	return dek_info;
+}
+
+static struct l_cipher *cipher_from_dek_info(const char *algid, const char *params,
+						const char *passphrase,
+						size_t *block_len)
+{
+	enum l_cipher_type type;
+	struct l_cipher *cipher;
+	struct l_checksum *md5;
+	uint8_t key[32];
+	size_t key_len;
+	bool ok;
+	L_AUTO_FREE_VAR(uint8_t *, iv) = NULL;
+	size_t iv_len;
+
+	if (!strcmp(algid, "DES-CBC")) {
+		type = L_CIPHER_DES_CBC;
+		key_len = 8;
+		iv_len = 8;
+	} else if (!strcmp(algid, "DES-EDE3-CBC")) {
+		type = L_CIPHER_DES3_EDE_CBC;
+		key_len = 24;
+		iv_len = 8;
+	} else if (!strcmp(algid, "AES-128-CBC")) {
+		type = L_CIPHER_AES_CBC;
+		key_len = 16;
+		iv_len = 16;
+	} else if (!strcmp(algid, "AES-192-CBC")) {
+		type = L_CIPHER_AES_CBC;
+		key_len = 24;
+		iv_len = 16;
+	} else if (!strcmp(algid, "AES-256-CBC")) {
+		type = L_CIPHER_AES_CBC;
+		key_len = 32;
+		iv_len = 16;
+	} else
+		return NULL;
+
+	if (!params || strlen(params) != 2 * iv_len)
+		return NULL;
+
+	*block_len = iv_len;
+
+	iv = l_util_from_hexstring(params, &iv_len);
+	if (!iv)
+		return NULL;
+
+	/*
+	 * The encryption key is the MD5(password | IV[:8]), this comes from
+	 * opessl's crypto/evp/evp_key.c:EVP_BytesToKey() and doesn't seem to
+	 * be backed by any standard:
+	 * https://web.archive.org/web/20190528100132/https://latacora.singles/2018/08/03/the-default-openssh.html
+	 */
+	md5 = l_checksum_new(L_CHECKSUM_MD5);
+	if (!md5)
+		return NULL;
+
+	ok = l_checksum_update(md5, passphrase, strlen(passphrase)) &&
+		l_checksum_update(md5, iv, 8) &&
+		l_checksum_get_digest(md5, key, 16) == 16;
+
+	if (ok && key_len > 16) {
+		l_checksum_reset(md5);
+		ok = l_checksum_update(md5, key, 16) &&
+			l_checksum_update(md5, passphrase, strlen(passphrase)) &&
+			l_checksum_update(md5, iv, 8) &&
+			l_checksum_get_digest(md5, key + 16, 16) == 16;
+	}
+
+	l_checksum_free(md5);
+
+	if (!ok)
+		return NULL;
+
+	cipher  = l_cipher_new(type, key, key_len);
+	if (!cipher)
+		return NULL;
+
+	if (l_cipher_set_iv(cipher, iv, iv_len))
+		return cipher;
+
+	l_cipher_free(cipher);
+	return NULL;
+}
+
 static struct l_key *pem_load_private_key(uint8_t *content,
 						size_t len,
 						char *label,
 						const char *passphrase,
+						char *headers,
 						bool *encrypted)
 {
 	struct l_key *pkey = NULL;
@@ -405,8 +610,13 @@ static struct l_key *pem_load_private_key(uint8_t *content,
 	 * the PKCS#8/RFC5958 PrivateKeyInfo structure -- supported
 	 * directly by the pkcs8-key-parser kernel module.
 	 */
-	if (!strcmp(label, "PRIVATE KEY"))
+	if (!strcmp(label, "PRIVATE KEY")) {
+		/* RFC822 Headers explicitly not allowed in RFC7468 */
+		if (headers)
+			goto err;
+
 		goto done;
+	}
 
 	/*
 	 * RFC7468 Section 11-compatible encrypted private key label
@@ -429,6 +639,10 @@ static struct l_key *pem_load_private_key(uint8_t *content,
 		if (!passphrase)
 			goto err;
 
+		/* RFC822 Headers explicitly not allowed in RFC7468 */
+		if (headers)
+			goto err;
+
 		/* Technically this is BER, not limited to DER */
 		key_info = asn1_der_find_elem(content, len, 0, &tag,
 						&key_info_len);
@@ -486,18 +700,10 @@ static struct l_key *pem_load_private_key(uint8_t *content,
 	}
 
 	/*
-	 * Legacy RSA private key label aka. SSLeay format label, created
-	 * by most software but not documented in an RFC.  Encodes the
+	 * Legacy RSA private key label aka. SSLeay format, understood by
+	 * most software but not documented in an RFC.  Encodes the
 	 * PKCS#1/RFC8017 RSAPrivateKey structure.  We wrap it in a PKCS#8
 	 * PrivateKeyInfo for the pkcs8-key-parser module.
-	 *
-	 * TODO: decrypt RSA PRIVATE KEY format encrypted keys
-	 * as produced by "openssl rsa" commands.  These are incompatible
-	 * with RFC7468 parsing because of the RFC822 headers present
-	 * before base64-encoded data.  The format is documented in
-	 * RFC1421 and the encryption algorithms in RFC1423 although
-	 * openssl allows many more algorithms than those documented.
-	 * Then wrap in a PrivateKeyInfo like above.
 	 */
 	if (!strcmp(label, "RSA PRIVATE KEY")) {
 		const uint8_t *data;
@@ -510,6 +716,8 @@ static struct l_key *pem_load_private_key(uint8_t *content,
 		size_t private_key_len;
 		uint8_t *one_asymmetric_key;
 		uint8_t *ptr;
+		const char *dekalgid;
+		const char *dekparameters;
 
 		static const uint8_t version0[] = {
 			ASN1_ID_INTEGER, 0x01, 0x00
@@ -521,6 +729,54 @@ static struct l_key *pem_load_private_key(uint8_t *content,
 			ASN1_ID_NULL, 0x00,
 		};
 
+		/*
+		 * "openssl rsa" can produce encrypted PKCS#1-formatted keys.
+		 * These are incompatible with RFC7468 parsing because of the
+		 * RFC822 headers present but the format is the same as
+		 * documented in RFC1421.  The encryption algorithms are
+		 * supposed to be the ones defined in RFC1423 but that would
+		 * be only DES-CBC while openssl allows other algorithms.
+		 * When decrypted we get the RSAPrivateKey struct and proceed
+		 * like with the unencrypted format.
+		 */
+		dekalgid = parse_rfc1421_dek_info(headers, &dekparameters);
+		if (dekalgid) {
+			struct l_cipher *alg;
+			bool r;
+			int i;
+			size_t block_len;
+
+			if (encrypted)
+				*encrypted = true;
+
+			if (!passphrase)
+				goto err;
+
+			alg = cipher_from_dek_info(dekalgid, dekparameters,
+							passphrase, &block_len);
+			if (!alg)
+				goto err;
+
+			if (len % block_len || !len)
+				goto err;
+
+			r = l_cipher_decrypt(alg, content, content, len);
+			l_cipher_free(alg);
+
+			if (!r)
+				goto err;
+
+			/* Remove padding like in RFC1423 Section 1.1 */
+			if (content[len - 1] > block_len)
+				goto err;
+
+			for (i = 1; i < content[len - 1]; i++)
+				if (content[len - 1 - i] != content[len - 1])
+					goto err;
+
+			len -= content[len - 1];
+		}
+
 		/*
 		 * Sanity check that it's a version 0 or 1 RSAPrivateKey
 		 * structure with the 8 integers, if it's not, make a last
@@ -586,6 +842,7 @@ err:
 	}
 
 	l_free(label);
+	l_free(headers);
 	return pkey;
 }
 
@@ -597,16 +854,18 @@ LIB_EXPORT struct l_key *l_pem_load_private_key_from_data(const void *buf,
 	uint8_t *content;
 	char *label;
 	size_t len;
+	char *headers;
 
 	if (encrypted)
 		*encrypted = false;
 
-	content = pem_load_buffer(buf, buf_len, &label, &len);
+	content = pem_load_buffer(buf, buf_len, &label, &len, &headers);
 
 	if (!content)
 		return NULL;
 
-	return pem_load_private_key(content, len, label, passphrase, encrypted);
+	return pem_load_private_key(content, len, label, passphrase, headers,
+					encrypted);
 }
 
 /**
@@ -632,14 +891,16 @@ LIB_EXPORT struct l_key *l_pem_load_private_key(const char *filename,
 	uint8_t *content;
 	char *label;
 	size_t len;
+	char *headers;
 
 	if (encrypted)
 		*encrypted = false;
 
-	content = l_pem_load_file(filename, &label, &len);
+	content = pem_load_file(filename, &label, &len, &headers);
 
 	if (!content)
 		return NULL;
 
-	return pem_load_private_key(content, len, label, passphrase, encrypted);
+	return pem_load_private_key(content, len, label, passphrase, headers,
+					encrypted);
 }
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/5] examples: More error messages in https-{client, server}-test
  2020-11-20 20:28 [PATCH 1/5] pem: Parse PKCS#1 formatted private keys Andrew Zaborowski
  2020-11-20 20:28 ` [PATCH 2/5] pem: Decrypt PKCS#1 encrypted " Andrew Zaborowski
@ 2020-11-20 20:28 ` Andrew Zaborowski
  2020-11-20 20:28 ` [PATCH 4/5] treewide: Rename test private keys to include format Andrew Zaborowski
  2020-11-20 20:28 ` [PATCH 5/5] unit: Test loading PKCS#1 PEM private key files Andrew Zaborowski
  3 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2020-11-20 20:28 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 7106 bytes --]

Change the error messages to go to stderr and add messages on
certificate and key loading errors.
---
 examples/https-client-test.c | 39 ++++++++++++++++++++++++--------
 examples/https-server-test.c | 44 ++++++++++++++++++++++++------------
 2 files changed, 59 insertions(+), 24 deletions(-)

diff --git a/examples/https-client-test.c b/examples/https-client-test.c
index eaa7900..2c8d020 100644
--- a/examples/https-client-test.c
+++ b/examples/https-client-test.c
@@ -67,7 +67,7 @@ static void https_tls_disconnected(enum l_tls_alert_desc reason, bool remote,
 					void *user_data)
 {
 	if (reason)
-		printf("TLS error: %s\n", l_tls_alert_to_str(reason));
+		fprintf(stderr, "TLS error: %s\n", l_tls_alert_to_str(reason));
 	l_main_quit();
 }
 
@@ -137,6 +137,7 @@ int main(int argc, char *argv[])
 	struct l_certchain *cert = NULL;
 	struct l_key *priv_key = NULL;
 	struct l_queue *ca_cert = NULL;
+	bool encrypted;
 
 	if (argc != 2 && argc != 3 && argc != 6) {
 		printf("Usage: %s <https-host-name> [<ca-cert-path> "
@@ -153,19 +154,19 @@ int main(int argc, char *argv[])
 	hostname = argv[1];
 	he = gethostbyname(hostname);
 	if (!he) {
-		printf("gethostbyname: %s\n", strerror(errno));
+		fprintf(stderr, "gethostbyname: %s\n", strerror(errno));
 		return -1;
 	}
 
 	addr_list = (struct in_addr **) he->h_addr_list;
 	if (!addr_list) {
-		printf("No host addresses found\n");
+		fprintf(stderr, "No host addresses found\n");
 		return -1;
 	}
 
 	fd = socket(AF_INET, SOCK_STREAM, 0);
 	if (fd < 0) {
-		printf("socket: %s\n", strerror(errno));
+		fprintf(stderr, "socket: %s\n", strerror(errno));
 		return -1;
 	}
 
@@ -174,7 +175,7 @@ int main(int argc, char *argv[])
 	addr.sin_port = htons(443);
 	memcpy(&addr.sin_addr, addr_list[0], sizeof(addr.sin_addr));
 	if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		printf("connect: %s\n", strerror(errno));
+		fprintf(stderr, "connect: %s\n", strerror(errno));
 		return -1;
 	}
 
@@ -192,14 +193,32 @@ int main(int argc, char *argv[])
 	if (getenv("TLS_DEBUG"))
 		l_tls_set_debug(tls, https_tls_debug_cb, NULL, NULL);
 
-	if (argc >= 3)
+	if (argc >= 3) {
 		ca_cert = l_pem_load_certificate_list(argv[2]);
+		if (!cert) {
+			fprintf(stderr, "Couldn't load the CA certificates\n");
+			return -1;
+		}
+	}
 
-	if (argc >= 4)
+	if (argc >= 4) {
 		cert = l_pem_load_certificate_chain(argv[3]);
+		if (!cert) {
+			fprintf(stderr,
+				"Couldn't load the server certificate\n");
+			return -1;
+		}
+	}
 
-	if (argc >= 6)
-		priv_key = l_pem_load_private_key(argv[4], argv[5], NULL);
+	if (argc >= 6) {
+		priv_key = l_pem_load_private_key(argv[4], argv[5], &encrypted);
+		if (!priv_key) {
+			fprintf(stderr,
+				"Couldn't load the client private key%s\n",
+				encrypted ? " (encrypted)" : "");
+			return -1;
+		}
+	}
 
 	auth_ok = (argc <= 2 || l_tls_set_cacert(tls, ca_cert)) &&
 		(argc <= 5 ||
@@ -209,7 +228,7 @@ int main(int argc, char *argv[])
 	if (tls && auth_ok)
 		l_main_run();
 	else {
-		printf("TLS setup failed\n");
+		fprintf(stderr, "TLS setup failed\n");
 		l_queue_destroy(ca_cert, (l_queue_destroy_func_t) l_cert_free);
 		l_certchain_free(cert);
 		l_key_free(priv_key);
diff --git a/examples/https-server-test.c b/examples/https-server-test.c
index 2512601..53a11e2 100644
--- a/examples/https-server-test.c
+++ b/examples/https-server-test.c
@@ -42,7 +42,7 @@ bool served;
 static void https_io_disconnect(struct l_io *io, void *user_data)
 {
 	if (!served)
-		printf("Disconnected before serving a page\n");
+		fprintf(stderr, "Disconnected before serving a page\n");
 	l_main_quit();
 }
 
@@ -54,7 +54,7 @@ static bool https_io_read(struct l_io *io, void *user_data)
 	l = read(l_io_get_fd(io), buf, sizeof(buf));
 	if (l == 0) {
 		if (!served)
-			printf("EOF before serving a page\n");
+			fprintf(stderr, "EOF before serving a page\n");
 		l_main_quit();
 	} else if (l > 0)
 		l_tls_handle_rx(tls, buf, l);
@@ -66,7 +66,7 @@ static void https_tls_disconnected(enum l_tls_alert_desc reason, bool remote,
 					void *user_data)
 {
 	if (reason)
-		printf("TLS error: %s\n", l_tls_alert_to_str(reason));
+		fprintf(stderr, "TLS error: %s\n", l_tls_alert_to_str(reason));
 	l_main_quit();
 }
 
@@ -93,7 +93,7 @@ static void https_tls_write(const uint8_t *data, size_t len, void *user_data)
 	while (len) {
 		r = send(l_io_get_fd(io), data, len, MSG_NOSIGNAL);
 		if (r < 0) {
-			printf("send: %s\n", strerror(errno));
+			fprintf(stderr, "send: %s\n", strerror(errno));
 			l_main_quit();
 			break;
 		}
@@ -123,6 +123,7 @@ int main(int argc, char *argv[])
 	struct l_certchain *cert;
 	struct l_key *priv_key;
 	struct l_queue *ca_cert = NULL;
+	bool encrypted;
 
 	if (argc != 4 && argc != 5) {
 		printf("Usage: %s <server-cert-path> <server-key-path> "
@@ -146,11 +147,11 @@ int main(int argc, char *argv[])
 	addr.sin_port = htons(1234);
 
 	if (bind(listenfd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
-		printf("bind: %s\n", strerror(errno));
+		fprintf(stderr, "bind: %s\n", strerror(errno));
 		return -1;
 	}
 	if (listen(listenfd, 1) == -1) {
-		printf("listen: %s\n", strerror(errno));
+		fprintf(stderr, "listen: %s\n", strerror(errno));
 		return -1;
 	}
 
@@ -159,13 +160,34 @@ int main(int argc, char *argv[])
 	fd = accept(listenfd, NULL, NULL);
 	close(listenfd);
 	if (fd == -1) {
-		printf("accept: %s\n", strerror(errno));
+		fprintf(stderr, "accept: %s\n", strerror(errno));
 		return -1;
 	}
 
 	if (!l_main_init())
 		return -1;
 
+	cert = l_pem_load_certificate_chain(argv[1]);
+	if (!cert) {
+		fprintf(stderr, "Couldn't load the server certificate\n");
+		return -1;
+	}
+
+	priv_key = l_pem_load_private_key(argv[2], argv[3], &encrypted);
+	if (!priv_key) {
+		fprintf(stderr, "Couldn't load the server private key%s\n",
+			encrypted ? " (encrypted)" : "");
+		return -1;
+	}
+
+	if (argc >= 5) {
+		ca_cert = l_pem_load_certificate_list(argv[4]);
+		if (!cert) {
+			fprintf(stderr, "Couldn't load the CA certificates\n");
+			return -1;
+		}
+	}
+
 	io = l_io_new(fd);
 	l_io_set_close_on_destroy(io, true);
 	l_io_set_read_handler(io, https_io_read, tls, NULL);
@@ -177,12 +199,6 @@ int main(int argc, char *argv[])
 	if (getenv("TLS_DEBUG"))
 		l_tls_set_debug(tls, https_tls_debug_cb, NULL, NULL);
 
-	cert = l_pem_load_certificate_chain(argv[1]);
-	priv_key = l_pem_load_private_key(argv[2], argv[3], NULL);
-
-	if (argc >= 5)
-		ca_cert = l_pem_load_certificate_list(argv[4]);
-
 	auth_ok = l_tls_set_auth_data(tls, cert, priv_key) &&
 		(argc <= 4 || l_tls_set_cacert(tls, ca_cert)) &&
 		l_tls_start(tls);
@@ -190,7 +206,7 @@ int main(int argc, char *argv[])
 	if (tls && auth_ok)
 		l_main_run();
 	else {
-		printf("TLS setup failed\n");
+		fprintf(stderr, "TLS setup failed\n");
 		l_queue_destroy(ca_cert, (l_queue_destroy_func_t) l_cert_free);
 		l_certchain_free(cert);
 		l_key_free(priv_key);
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5] treewide: Rename test private keys to include format
  2020-11-20 20:28 [PATCH 1/5] pem: Parse PKCS#1 formatted private keys Andrew Zaborowski
  2020-11-20 20:28 ` [PATCH 2/5] pem: Decrypt PKCS#1 encrypted " Andrew Zaborowski
  2020-11-20 20:28 ` [PATCH 3/5] examples: More error messages in https-{client, server}-test Andrew Zaborowski
@ 2020-11-20 20:28 ` Andrew Zaborowski
  2020-11-20 20:28 ` [PATCH 5/5] unit: Test loading PKCS#1 PEM private key files Andrew Zaborowski
  3 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2020-11-20 20:28 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 6533 bytes --]

Include pkcs1 or pkcs8 in the names of the test client private keys.
---
 Makefile.am     | 39 ++++++++++++++++++++-------------------
 unit/test-pem.c | 17 +++++++++--------
 2 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index e358546..546a6aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -211,15 +211,16 @@ cert_tests = unit/test-pem \
 cert_files = unit/cert-chain.pem \
 			unit/cert-entity-int.pem \
 			unit/cert-server.pem \
-			unit/cert-client.pem \
 			unit/cert-server-key-pkcs8.pem \
+			unit/cert-client.pem \
+			unit/cert-client-key-pkcs1.pem \
 			unit/cert-client-key-pkcs8.pem \
-			unit/cert-client-key-md5-des.pem \
-			unit/cert-client-key-sha1-des.pem \
-			unit/cert-client-key-v2-des.pem \
-			unit/cert-client-key-v2-des-ede3.pem \
-			unit/cert-client-key-v2-aes128.pem \
-			unit/cert-client-key-v2-aes256.pem \
+			unit/cert-client-key-pkcs8-md5-des.pem \
+			unit/cert-client-key-pkcs8-sha1-des.pem \
+			unit/cert-client-key-pkcs8-v2-des.pem \
+			unit/cert-client-key-pkcs8-v2-des-ede3.pem \
+			unit/cert-client-key-pkcs8-v2-aes128.pem \
+			unit/cert-client-key-pkcs8-v2-aes256.pem \
 			unit/cert-no-keyid.pem
 
 cert_checks = unit/cert-intca \
@@ -416,37 +417,37 @@ unit/cert-server.pem: unit/cert-server.csr unit/cert-ca.pem unit/gencerts.cnf
 unit/cert-server: unit/cert-server.pem unit/cert-ca.pem
 	$(AM_V_GEN)openssl verify -CAfile $(builddir)/unit/cert-ca.pem $<
 
-unit/cert-client-key.pem:
+unit/cert-client-key-pkcs1.pem:
 	$(AM_V_GEN)openssl genrsa -out $@ $($(AM_V_P)_redirect_openssl)
 
-unit/cert-client-key-pkcs8.pem: unit/cert-client-key.pem
+unit/cert-client-key-pkcs8.pem: unit/cert-client-key-pkcs1.pem
 	$(AM_V_GEN)openssl pkcs8 -topk8 -nocrypt -in $< -out $@
 
-unit/cert-client-key-md5-des.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-md5-des.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v1 PBE-MD5-DES -passout pass:abc
 
-unit/cert-client-key-sha1-des.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-sha1-des.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v1 PBE-SHA1-DES -passout pass:abc
 
-unit/cert-client-key-v2-des.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-des.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 des-cbc -v2prf hmacWithSHA1 -passout pass:abc
 
-unit/cert-client-key-v2-des-ede3.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-des-ede3.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 des-ede3-cbc -v2prf hmacWithSHA224 -passout pass:abc
 
-unit/cert-client-key-v2-aes128.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-aes128.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 aes128 -v2prf hmacWithSHA256 -passout pass:abc
 
-unit/cert-client-key-v2-aes256.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-aes256.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 aes256 -v2prf hmacWithSHA512 -passout pass:abc
 
-unit/cert-client.csr: unit/cert-client-key.pem unit/gencerts.cnf
+unit/cert-client.csr: unit/cert-client-key-pkcs1.pem unit/gencerts.cnf
 	$(AM_V_GEN)openssl req -new -extensions cert_ext \
 			-config $(srcdir)/unit/gencerts.cnf \
 			-subj '/O=Bar Example Organization/CN=Bar Example Organization/emailAddress=bar(a)mail.example' \
@@ -512,7 +513,7 @@ unit/cert-ca2.pem: unit/cert-ca-key.pem unit/gencerts.cnf
 			-subj '/O=International Union of Example Organizations/CN=Certificate issuer guy/emailAddress=ca-no-akid(a)mail.example' \
 			-key $< -sha256 -days 10000 -out $@
 
-unit/cert-no-keyid.csr: unit/cert-client-key.pem unit/gencerts.cnf
+unit/cert-no-keyid.csr: unit/cert-client-key-pkcs1.pem unit/gencerts.cnf
 	$(AM_V_GEN)openssl req -new \
 			-config $(srcdir)/unit/gencerts.cnf \
 			-subj '/O=Baz Example Organization/CN=Baz Example Organization/emailAddress=baz@mail.example' \
@@ -539,9 +540,9 @@ unit/key-ciphertext.dat: unit/plaintext.txt unit/cert-client.pem
 unit/key-ciphertext.h: unit/key-ciphertext.dat
 	$(AM_V_GEN)xxd -i < $< > $@
 
-unit/key-signature.dat: unit/plaintext.txt unit/cert-client-key.pem
+unit/key-signature.dat: unit/plaintext.txt unit/cert-client-key-pkcs1.pem
 	$(AM_V_GEN)openssl rsautl -sign -pkcs -in $< \
-			-inkey $(builddir)/unit/cert-client-key.pem -out $@
+			-inkey $(builddir)/unit/cert-client-key-pkcs1.pem -out $@
 
 unit/key-signature.h: unit/key-signature.dat
 	$(AM_V_GEN)xxd -i < $< > $@
diff --git a/unit/test-pem.c b/unit/test-pem.c
index a1e8110..e81ddde 100644
--- a/unit/test-pem.c
+++ b/unit/test-pem.c
@@ -326,18 +326,19 @@ int main(int argc, char *argv[])
 
 	l_test_add("pem/v1 MD5AndDES encrypted Private Key",
 			test_encrypted_pkey,
-			CERTDIR "cert-client-key-md5-des.pem");
+			CERTDIR "cert-client-key-pkcs8-md5-des.pem");
 	l_test_add("pem/v1 SHA1AndDES encrypted Private Key",
 			test_encrypted_pkey,
-			CERTDIR "cert-client-key-sha1-des.pem");
+			CERTDIR "cert-client-key-pkcs8-sha1-des.pem");
 	l_test_add("pem/v2 DES encrypted Private Key", test_encrypted_pkey,
-			CERTDIR "cert-client-key-v2-des.pem");
+			CERTDIR "cert-client-key-pkcs8-v2-des.pem");
 
 	if (l_cipher_is_supported(L_CIPHER_DES3_EDE_CBC) &&
-			l_checksum_is_supported(L_CHECKSUM_SHA224, false))
+			l_checksum_is_supported(L_CHECKSUM_SHA224, false)) {
 		l_test_add("pem/v2 DES EDE3 encrypted Private Key",
-				test_encrypted_pkey,
-				CERTDIR "cert-client-key-v2-des-ede3.pem");
+				test_encrypted_pkey, CERTDIR
+				"cert-client-key-pkcs8-v2-des-ede3.pem");
+	}
 
 	if (!l_cipher_is_supported(L_CIPHER_AES))
 		goto done;
@@ -345,12 +346,12 @@ int main(int argc, char *argv[])
 	if (l_checksum_is_supported(L_CHECKSUM_SHA256, false))
 		l_test_add("pem/v2 AES128 encrypted Private Key",
 				test_encrypted_pkey,
-				CERTDIR "cert-client-key-v2-aes128.pem");
+				CERTDIR "cert-client-key-pkcs8-v2-aes128.pem");
 
 	if (l_checksum_is_supported(L_CHECKSUM_SHA512, false))
 		l_test_add("pem/v2 AES256 encrypted Private Key",
 				test_encrypted_pkey,
-				CERTDIR "cert-client-key-v2-aes256.pem");
+				CERTDIR "cert-client-key-pkcs8-v2-aes256.pem");
 
 done:
 	return l_test_run();
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/5] unit: Test loading PKCS#1 PEM private key files
  2020-11-20 20:28 [PATCH 1/5] pem: Parse PKCS#1 formatted private keys Andrew Zaborowski
                   ` (2 preceding siblings ...)
  2020-11-20 20:28 ` [PATCH 4/5] treewide: Rename test private keys to include format Andrew Zaborowski
@ 2020-11-20 20:28 ` Andrew Zaborowski
  3 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2020-11-20 20:28 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 5225 bytes --]

---
 Makefile.am     | 20 ++++++++++++++
 unit/test-pem.c | 71 ++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 84 insertions(+), 7 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 546a6aa..28082aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -214,6 +214,11 @@ cert_files = unit/cert-chain.pem \
 			unit/cert-server-key-pkcs8.pem \
 			unit/cert-client.pem \
 			unit/cert-client-key-pkcs1.pem \
+			unit/cert-client-key-pkcs1-des.pem \
+			unit/cert-client-key-pkcs1-des3.pem \
+			unit/cert-client-key-pkcs1-aes128.pem \
+			unit/cert-client-key-pkcs1-aes192.pem \
+			unit/cert-client-key-pkcs1-aes256.pem \
 			unit/cert-client-key-pkcs8.pem \
 			unit/cert-client-key-pkcs8-md5-des.pem \
 			unit/cert-client-key-pkcs8-sha1-des.pem \
@@ -420,6 +425,21 @@ unit/cert-server: unit/cert-server.pem unit/cert-ca.pem
 unit/cert-client-key-pkcs1.pem:
 	$(AM_V_GEN)openssl genrsa -out $@ $($(AM_V_P)_redirect_openssl)
 
+unit/cert-client-key-pkcs1-des.pem: unit/cert-client-key-pkcs1.pem
+	$(AM_V_GEN)openssl rsa -in $< -out $@ -des -passout pass:abc
+
+unit/cert-client-key-pkcs1-des3.pem: unit/cert-client-key-pkcs1.pem
+	$(AM_V_GEN)openssl rsa -in $< -out $@ -des3 -passout pass:abc
+
+unit/cert-client-key-pkcs1-aes128.pem: unit/cert-client-key-pkcs1.pem
+	$(AM_V_GEN)openssl rsa -in $< -out $@ -aes128 -passout pass:abc
+
+unit/cert-client-key-pkcs1-aes192.pem: unit/cert-client-key-pkcs1.pem
+	$(AM_V_GEN)openssl rsa -in $< -out $@ -aes192 -passout pass:abc
+
+unit/cert-client-key-pkcs1-aes256.pem: unit/cert-client-key-pkcs1.pem
+	$(AM_V_GEN)openssl rsa -in $< -out $@ -aes256 -passout pass:abc
+
 unit/cert-client-key-pkcs8.pem: unit/cert-client-key-pkcs1.pem
 	$(AM_V_GEN)openssl pkcs8 -topk8 -nocrypt -in $< -out $@
 
diff --git a/unit/test-pem.c b/unit/test-pem.c
index e81ddde..95315fc 100644
--- a/unit/test-pem.c
+++ b/unit/test-pem.c
@@ -257,6 +257,39 @@ static void test_pem(const void *data)
 	l_free(decoded);
 }
 
+static void test_unencrypted_pkey(const void *data)
+{
+	const char *pkcs1_pem = CERTDIR "cert-client-key-pkcs1.pem";
+	const char *pkcs8_pem = CERTDIR "cert-client-key-pkcs8.pem";
+	bool is_encrypted;
+	size_t size;
+	uint8_t encrypted1[256], encrypted2[256], plaintext[256];
+	struct l_key *pkey1, *pkey2;
+	bool is_public;
+
+	pkey1 = l_pem_load_private_key(pkcs1_pem, NULL, &is_encrypted);
+	assert(pkey1);
+	assert(!is_encrypted);
+
+	pkey2 = l_pem_load_private_key(pkcs8_pem, NULL, &is_encrypted);
+	assert(pkey2);
+	assert(!is_encrypted);
+
+	memset(plaintext, 42, 256);
+	assert(l_key_get_info(pkey1, L_KEY_RSA_RAW, L_CHECKSUM_NONE,
+				&size, &is_public));
+	assert(size == 2048);
+	assert(!is_public);
+	assert(l_key_encrypt(pkey1, L_KEY_RSA_RAW, L_CHECKSUM_NONE,
+				plaintext, encrypted1, 256, 256) == 256);
+	assert(l_key_encrypt(pkey2, L_KEY_RSA_RAW, L_CHECKSUM_NONE,
+				plaintext, encrypted2, 256, 256) == 256);
+	assert(!memcmp(encrypted1, encrypted2, 256));
+
+	l_key_free(pkey1);
+	l_key_free(pkey2);
+}
+
 static void test_encrypted_pkey(const void *data)
 {
 	const char *encrypted_pem = data;
@@ -324,6 +357,9 @@ int main(int argc, char *argv[])
 			!l_key_is_supported(L_KEY_FEATURE_CRYPTO))
 		goto done;
 
+	l_test_add("pem/PKCS#1 vs. PKCS#8 unenecrypted Private Key",
+			test_unencrypted_pkey, NULL);
+
 	l_test_add("pem/v1 MD5AndDES encrypted Private Key",
 			test_encrypted_pkey,
 			CERTDIR "cert-client-key-pkcs8-md5-des.pem");
@@ -340,18 +376,39 @@ int main(int argc, char *argv[])
 				"cert-client-key-pkcs8-v2-des-ede3.pem");
 	}
 
-	if (!l_cipher_is_supported(L_CIPHER_AES))
-		goto done;
-
-	if (l_checksum_is_supported(L_CHECKSUM_SHA256, false))
-		l_test_add("pem/v2 AES128 encrypted Private Key",
+	if (l_cipher_is_supported(L_CIPHER_AES)) {
+		if (l_checksum_is_supported(L_CHECKSUM_SHA256, false))
+			l_test_add("pem/v2 AES128 encrypted Private Key",
 				test_encrypted_pkey,
 				CERTDIR "cert-client-key-pkcs8-v2-aes128.pem");
 
-	if (l_checksum_is_supported(L_CHECKSUM_SHA512, false))
-		l_test_add("pem/v2 AES256 encrypted Private Key",
+		if (l_checksum_is_supported(L_CHECKSUM_SHA512, false))
+			l_test_add("pem/v2 AES256 encrypted Private Key",
 				test_encrypted_pkey,
 				CERTDIR "cert-client-key-pkcs8-v2-aes256.pem");
+	}
+
+	l_test_add("pem/PKCS#1 DES-encrypted RSA Private Key",
+			test_encrypted_pkey,
+			CERTDIR "cert-client-key-pkcs1-des.pem");
+
+	if (l_cipher_is_supported(L_CIPHER_DES3_EDE_CBC))
+		l_test_add("pem/PKCS#1 DES-EDE3-encrypted RSA Private Key",
+				test_encrypted_pkey,
+				CERTDIR "cert-client-key-pkcs1-des3.pem");
+
+
+	if (l_cipher_is_supported(L_CIPHER_AES_CBC)) {
+		l_test_add("pem/PKCS#1 AES128-encrypted RSA Private Key",
+				test_encrypted_pkey,
+				CERTDIR "cert-client-key-pkcs1-aes128.pem");
+		l_test_add("pem/PKCS#1 AES192-encrypted RSA Private Key",
+				test_encrypted_pkey,
+				CERTDIR "cert-client-key-pkcs1-aes192.pem");
+		l_test_add("pem/PKCS#1 AES256-encrypted RSA Private Key",
+				test_encrypted_pkey,
+				CERTDIR "cert-client-key-pkcs1-aes256.pem");
+	}
 
 done:
 	return l_test_run();
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5] treewide: Rename test private keys to include format
  2020-11-23 11:54 [PATCH 1/5] pem: Parse PKCS#1 formatted private keys Andrew Zaborowski
@ 2020-11-23 11:54 ` Andrew Zaborowski
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2020-11-23 11:54 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 6533 bytes --]

Include pkcs1 or pkcs8 in the names of the test client private keys.
---
 Makefile.am     | 39 ++++++++++++++++++++-------------------
 unit/test-pem.c | 17 +++++++++--------
 2 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index e358546..546a6aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -211,15 +211,16 @@ cert_tests = unit/test-pem \
 cert_files = unit/cert-chain.pem \
 			unit/cert-entity-int.pem \
 			unit/cert-server.pem \
-			unit/cert-client.pem \
 			unit/cert-server-key-pkcs8.pem \
+			unit/cert-client.pem \
+			unit/cert-client-key-pkcs1.pem \
 			unit/cert-client-key-pkcs8.pem \
-			unit/cert-client-key-md5-des.pem \
-			unit/cert-client-key-sha1-des.pem \
-			unit/cert-client-key-v2-des.pem \
-			unit/cert-client-key-v2-des-ede3.pem \
-			unit/cert-client-key-v2-aes128.pem \
-			unit/cert-client-key-v2-aes256.pem \
+			unit/cert-client-key-pkcs8-md5-des.pem \
+			unit/cert-client-key-pkcs8-sha1-des.pem \
+			unit/cert-client-key-pkcs8-v2-des.pem \
+			unit/cert-client-key-pkcs8-v2-des-ede3.pem \
+			unit/cert-client-key-pkcs8-v2-aes128.pem \
+			unit/cert-client-key-pkcs8-v2-aes256.pem \
 			unit/cert-no-keyid.pem
 
 cert_checks = unit/cert-intca \
@@ -416,37 +417,37 @@ unit/cert-server.pem: unit/cert-server.csr unit/cert-ca.pem unit/gencerts.cnf
 unit/cert-server: unit/cert-server.pem unit/cert-ca.pem
 	$(AM_V_GEN)openssl verify -CAfile $(builddir)/unit/cert-ca.pem $<
 
-unit/cert-client-key.pem:
+unit/cert-client-key-pkcs1.pem:
 	$(AM_V_GEN)openssl genrsa -out $@ $($(AM_V_P)_redirect_openssl)
 
-unit/cert-client-key-pkcs8.pem: unit/cert-client-key.pem
+unit/cert-client-key-pkcs8.pem: unit/cert-client-key-pkcs1.pem
 	$(AM_V_GEN)openssl pkcs8 -topk8 -nocrypt -in $< -out $@
 
-unit/cert-client-key-md5-des.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-md5-des.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v1 PBE-MD5-DES -passout pass:abc
 
-unit/cert-client-key-sha1-des.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-sha1-des.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v1 PBE-SHA1-DES -passout pass:abc
 
-unit/cert-client-key-v2-des.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-des.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 des-cbc -v2prf hmacWithSHA1 -passout pass:abc
 
-unit/cert-client-key-v2-des-ede3.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-des-ede3.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 des-ede3-cbc -v2prf hmacWithSHA224 -passout pass:abc
 
-unit/cert-client-key-v2-aes128.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-aes128.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 aes128 -v2prf hmacWithSHA256 -passout pass:abc
 
-unit/cert-client-key-v2-aes256.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-aes256.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 aes256 -v2prf hmacWithSHA512 -passout pass:abc
 
-unit/cert-client.csr: unit/cert-client-key.pem unit/gencerts.cnf
+unit/cert-client.csr: unit/cert-client-key-pkcs1.pem unit/gencerts.cnf
 	$(AM_V_GEN)openssl req -new -extensions cert_ext \
 			-config $(srcdir)/unit/gencerts.cnf \
 			-subj '/O=Bar Example Organization/CN=Bar Example Organization/emailAddress=bar(a)mail.example' \
@@ -512,7 +513,7 @@ unit/cert-ca2.pem: unit/cert-ca-key.pem unit/gencerts.cnf
 			-subj '/O=International Union of Example Organizations/CN=Certificate issuer guy/emailAddress=ca-no-akid(a)mail.example' \
 			-key $< -sha256 -days 10000 -out $@
 
-unit/cert-no-keyid.csr: unit/cert-client-key.pem unit/gencerts.cnf
+unit/cert-no-keyid.csr: unit/cert-client-key-pkcs1.pem unit/gencerts.cnf
 	$(AM_V_GEN)openssl req -new \
 			-config $(srcdir)/unit/gencerts.cnf \
 			-subj '/O=Baz Example Organization/CN=Baz Example Organization/emailAddress=baz@mail.example' \
@@ -539,9 +540,9 @@ unit/key-ciphertext.dat: unit/plaintext.txt unit/cert-client.pem
 unit/key-ciphertext.h: unit/key-ciphertext.dat
 	$(AM_V_GEN)xxd -i < $< > $@
 
-unit/key-signature.dat: unit/plaintext.txt unit/cert-client-key.pem
+unit/key-signature.dat: unit/plaintext.txt unit/cert-client-key-pkcs1.pem
 	$(AM_V_GEN)openssl rsautl -sign -pkcs -in $< \
-			-inkey $(builddir)/unit/cert-client-key.pem -out $@
+			-inkey $(builddir)/unit/cert-client-key-pkcs1.pem -out $@
 
 unit/key-signature.h: unit/key-signature.dat
 	$(AM_V_GEN)xxd -i < $< > $@
diff --git a/unit/test-pem.c b/unit/test-pem.c
index a1e8110..e81ddde 100644
--- a/unit/test-pem.c
+++ b/unit/test-pem.c
@@ -326,18 +326,19 @@ int main(int argc, char *argv[])
 
 	l_test_add("pem/v1 MD5AndDES encrypted Private Key",
 			test_encrypted_pkey,
-			CERTDIR "cert-client-key-md5-des.pem");
+			CERTDIR "cert-client-key-pkcs8-md5-des.pem");
 	l_test_add("pem/v1 SHA1AndDES encrypted Private Key",
 			test_encrypted_pkey,
-			CERTDIR "cert-client-key-sha1-des.pem");
+			CERTDIR "cert-client-key-pkcs8-sha1-des.pem");
 	l_test_add("pem/v2 DES encrypted Private Key", test_encrypted_pkey,
-			CERTDIR "cert-client-key-v2-des.pem");
+			CERTDIR "cert-client-key-pkcs8-v2-des.pem");
 
 	if (l_cipher_is_supported(L_CIPHER_DES3_EDE_CBC) &&
-			l_checksum_is_supported(L_CHECKSUM_SHA224, false))
+			l_checksum_is_supported(L_CHECKSUM_SHA224, false)) {
 		l_test_add("pem/v2 DES EDE3 encrypted Private Key",
-				test_encrypted_pkey,
-				CERTDIR "cert-client-key-v2-des-ede3.pem");
+				test_encrypted_pkey, CERTDIR
+				"cert-client-key-pkcs8-v2-des-ede3.pem");
+	}
 
 	if (!l_cipher_is_supported(L_CIPHER_AES))
 		goto done;
@@ -345,12 +346,12 @@ int main(int argc, char *argv[])
 	if (l_checksum_is_supported(L_CHECKSUM_SHA256, false))
 		l_test_add("pem/v2 AES128 encrypted Private Key",
 				test_encrypted_pkey,
-				CERTDIR "cert-client-key-v2-aes128.pem");
+				CERTDIR "cert-client-key-pkcs8-v2-aes128.pem");
 
 	if (l_checksum_is_supported(L_CHECKSUM_SHA512, false))
 		l_test_add("pem/v2 AES256 encrypted Private Key",
 				test_encrypted_pkey,
-				CERTDIR "cert-client-key-v2-aes256.pem");
+				CERTDIR "cert-client-key-pkcs8-v2-aes256.pem");
 
 done:
 	return l_test_run();
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5] treewide: Rename test private keys to include format
  2020-11-21  2:48 [PATCH 1/5] pem: Parse PKCS#1 formatted private keys Andrew Zaborowski
@ 2020-11-21  2:48 ` Andrew Zaborowski
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Zaborowski @ 2020-11-21  2:48 UTC (permalink / raw)
  To: ell

[-- Attachment #1: Type: text/plain, Size: 6533 bytes --]

Include pkcs1 or pkcs8 in the names of the test client private keys.
---
 Makefile.am     | 39 ++++++++++++++++++++-------------------
 unit/test-pem.c | 17 +++++++++--------
 2 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index e358546..546a6aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -211,15 +211,16 @@ cert_tests = unit/test-pem \
 cert_files = unit/cert-chain.pem \
 			unit/cert-entity-int.pem \
 			unit/cert-server.pem \
-			unit/cert-client.pem \
 			unit/cert-server-key-pkcs8.pem \
+			unit/cert-client.pem \
+			unit/cert-client-key-pkcs1.pem \
 			unit/cert-client-key-pkcs8.pem \
-			unit/cert-client-key-md5-des.pem \
-			unit/cert-client-key-sha1-des.pem \
-			unit/cert-client-key-v2-des.pem \
-			unit/cert-client-key-v2-des-ede3.pem \
-			unit/cert-client-key-v2-aes128.pem \
-			unit/cert-client-key-v2-aes256.pem \
+			unit/cert-client-key-pkcs8-md5-des.pem \
+			unit/cert-client-key-pkcs8-sha1-des.pem \
+			unit/cert-client-key-pkcs8-v2-des.pem \
+			unit/cert-client-key-pkcs8-v2-des-ede3.pem \
+			unit/cert-client-key-pkcs8-v2-aes128.pem \
+			unit/cert-client-key-pkcs8-v2-aes256.pem \
 			unit/cert-no-keyid.pem
 
 cert_checks = unit/cert-intca \
@@ -416,37 +417,37 @@ unit/cert-server.pem: unit/cert-server.csr unit/cert-ca.pem unit/gencerts.cnf
 unit/cert-server: unit/cert-server.pem unit/cert-ca.pem
 	$(AM_V_GEN)openssl verify -CAfile $(builddir)/unit/cert-ca.pem $<
 
-unit/cert-client-key.pem:
+unit/cert-client-key-pkcs1.pem:
 	$(AM_V_GEN)openssl genrsa -out $@ $($(AM_V_P)_redirect_openssl)
 
-unit/cert-client-key-pkcs8.pem: unit/cert-client-key.pem
+unit/cert-client-key-pkcs8.pem: unit/cert-client-key-pkcs1.pem
 	$(AM_V_GEN)openssl pkcs8 -topk8 -nocrypt -in $< -out $@
 
-unit/cert-client-key-md5-des.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-md5-des.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v1 PBE-MD5-DES -passout pass:abc
 
-unit/cert-client-key-sha1-des.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-sha1-des.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v1 PBE-SHA1-DES -passout pass:abc
 
-unit/cert-client-key-v2-des.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-des.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 des-cbc -v2prf hmacWithSHA1 -passout pass:abc
 
-unit/cert-client-key-v2-des-ede3.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-des-ede3.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 des-ede3-cbc -v2prf hmacWithSHA224 -passout pass:abc
 
-unit/cert-client-key-v2-aes128.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-aes128.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 aes128 -v2prf hmacWithSHA256 -passout pass:abc
 
-unit/cert-client-key-v2-aes256.pem: unit/cert-client-key-pkcs8.pem
+unit/cert-client-key-pkcs8-v2-aes256.pem: unit/cert-client-key-pkcs8.pem
 	$(AM_V_GEN)openssl pkcs8 -in $< -out $@ \
 			-topk8 -v2 aes256 -v2prf hmacWithSHA512 -passout pass:abc
 
-unit/cert-client.csr: unit/cert-client-key.pem unit/gencerts.cnf
+unit/cert-client.csr: unit/cert-client-key-pkcs1.pem unit/gencerts.cnf
 	$(AM_V_GEN)openssl req -new -extensions cert_ext \
 			-config $(srcdir)/unit/gencerts.cnf \
 			-subj '/O=Bar Example Organization/CN=Bar Example Organization/emailAddress=bar(a)mail.example' \
@@ -512,7 +513,7 @@ unit/cert-ca2.pem: unit/cert-ca-key.pem unit/gencerts.cnf
 			-subj '/O=International Union of Example Organizations/CN=Certificate issuer guy/emailAddress=ca-no-akid(a)mail.example' \
 			-key $< -sha256 -days 10000 -out $@
 
-unit/cert-no-keyid.csr: unit/cert-client-key.pem unit/gencerts.cnf
+unit/cert-no-keyid.csr: unit/cert-client-key-pkcs1.pem unit/gencerts.cnf
 	$(AM_V_GEN)openssl req -new \
 			-config $(srcdir)/unit/gencerts.cnf \
 			-subj '/O=Baz Example Organization/CN=Baz Example Organization/emailAddress=baz@mail.example' \
@@ -539,9 +540,9 @@ unit/key-ciphertext.dat: unit/plaintext.txt unit/cert-client.pem
 unit/key-ciphertext.h: unit/key-ciphertext.dat
 	$(AM_V_GEN)xxd -i < $< > $@
 
-unit/key-signature.dat: unit/plaintext.txt unit/cert-client-key.pem
+unit/key-signature.dat: unit/plaintext.txt unit/cert-client-key-pkcs1.pem
 	$(AM_V_GEN)openssl rsautl -sign -pkcs -in $< \
-			-inkey $(builddir)/unit/cert-client-key.pem -out $@
+			-inkey $(builddir)/unit/cert-client-key-pkcs1.pem -out $@
 
 unit/key-signature.h: unit/key-signature.dat
 	$(AM_V_GEN)xxd -i < $< > $@
diff --git a/unit/test-pem.c b/unit/test-pem.c
index a1e8110..e81ddde 100644
--- a/unit/test-pem.c
+++ b/unit/test-pem.c
@@ -326,18 +326,19 @@ int main(int argc, char *argv[])
 
 	l_test_add("pem/v1 MD5AndDES encrypted Private Key",
 			test_encrypted_pkey,
-			CERTDIR "cert-client-key-md5-des.pem");
+			CERTDIR "cert-client-key-pkcs8-md5-des.pem");
 	l_test_add("pem/v1 SHA1AndDES encrypted Private Key",
 			test_encrypted_pkey,
-			CERTDIR "cert-client-key-sha1-des.pem");
+			CERTDIR "cert-client-key-pkcs8-sha1-des.pem");
 	l_test_add("pem/v2 DES encrypted Private Key", test_encrypted_pkey,
-			CERTDIR "cert-client-key-v2-des.pem");
+			CERTDIR "cert-client-key-pkcs8-v2-des.pem");
 
 	if (l_cipher_is_supported(L_CIPHER_DES3_EDE_CBC) &&
-			l_checksum_is_supported(L_CHECKSUM_SHA224, false))
+			l_checksum_is_supported(L_CHECKSUM_SHA224, false)) {
 		l_test_add("pem/v2 DES EDE3 encrypted Private Key",
-				test_encrypted_pkey,
-				CERTDIR "cert-client-key-v2-des-ede3.pem");
+				test_encrypted_pkey, CERTDIR
+				"cert-client-key-pkcs8-v2-des-ede3.pem");
+	}
 
 	if (!l_cipher_is_supported(L_CIPHER_AES))
 		goto done;
@@ -345,12 +346,12 @@ int main(int argc, char *argv[])
 	if (l_checksum_is_supported(L_CHECKSUM_SHA256, false))
 		l_test_add("pem/v2 AES128 encrypted Private Key",
 				test_encrypted_pkey,
-				CERTDIR "cert-client-key-v2-aes128.pem");
+				CERTDIR "cert-client-key-pkcs8-v2-aes128.pem");
 
 	if (l_checksum_is_supported(L_CHECKSUM_SHA512, false))
 		l_test_add("pem/v2 AES256 encrypted Private Key",
 				test_encrypted_pkey,
-				CERTDIR "cert-client-key-v2-aes256.pem");
+				CERTDIR "cert-client-key-pkcs8-v2-aes256.pem");
 
 done:
 	return l_test_run();
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-11-23 11:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-20 20:28 [PATCH 1/5] pem: Parse PKCS#1 formatted private keys Andrew Zaborowski
2020-11-20 20:28 ` [PATCH 2/5] pem: Decrypt PKCS#1 encrypted " Andrew Zaborowski
2020-11-20 20:28 ` [PATCH 3/5] examples: More error messages in https-{client, server}-test Andrew Zaborowski
2020-11-20 20:28 ` [PATCH 4/5] treewide: Rename test private keys to include format Andrew Zaborowski
2020-11-20 20:28 ` [PATCH 5/5] unit: Test loading PKCS#1 PEM private key files Andrew Zaborowski
2020-11-21  2:48 [PATCH 1/5] pem: Parse PKCS#1 formatted private keys Andrew Zaborowski
2020-11-21  2:48 ` [PATCH 4/5] treewide: Rename test private keys to include format Andrew Zaborowski
2020-11-23 11:54 [PATCH 1/5] pem: Parse PKCS#1 formatted private keys Andrew Zaborowski
2020-11-23 11:54 ` [PATCH 4/5] treewide: Rename test private keys to include format Andrew Zaborowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.