[PATCH] unit/test-dbus: pick up dbus-daemon from $PATH
by Florian Klink
This allows running the unit tests in environments where `dbus-daemon`
isn't in /usr/bin, but in $PATH.
Signed-off-by: Florian Klink <flokli(a)flokli.de>
---
unit/test-dbus-message-fds.c | 4 ++--
unit/test-dbus-properties.c | 4 ++--
unit/test-dbus.c | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/unit/test-dbus-message-fds.c b/unit/test-dbus-message-fds.c
index 6f68bae..4b5662e 100644
--- a/unit/test-dbus-message-fds.c
+++ b/unit/test-dbus-message-fds.c
@@ -51,7 +51,7 @@ static bool start_dbus_daemon(void)
char *prg_envp[1];
pid_t pid;
- prg_argv[0] = "/usr/bin/dbus-daemon";
+ prg_argv[0] = "dbus-daemon";
prg_argv[1] = "--nopidfile";
prg_argv[2] = "--nofork";
prg_argv[3] = "--config-file=" UNITDIR "dbus.conf";
@@ -68,7 +68,7 @@ static bool start_dbus_daemon(void)
}
if (pid == 0) {
- execve(prg_argv[0], prg_argv, prg_envp);
+ execvpe(prg_argv[0], prg_argv, prg_envp);
exit(EXIT_SUCCESS);
}
diff --git a/unit/test-dbus-properties.c b/unit/test-dbus-properties.c
index b435062..049f0f4 100644
--- a/unit/test-dbus-properties.c
+++ b/unit/test-dbus-properties.c
@@ -49,7 +49,7 @@ static bool start_dbus_daemon(void)
char *prg_envp[1];
pid_t pid;
- prg_argv[0] = "/usr/bin/dbus-daemon";
+ prg_argv[0] = "dbus-daemon";
prg_argv[1] = "--nopidfile";
prg_argv[2] = "--nofork";
prg_argv[3] = "--config-file=" UNITDIR "dbus.conf";
@@ -66,7 +66,7 @@ static bool start_dbus_daemon(void)
}
if (pid == 0) {
- execve(prg_argv[0], prg_argv, prg_envp);
+ execvpe(prg_argv[0], prg_argv, prg_envp);
exit(EXIT_SUCCESS);
}
diff --git a/unit/test-dbus.c b/unit/test-dbus.c
index 67f0a7b..582847e 100644
--- a/unit/test-dbus.c
+++ b/unit/test-dbus.c
@@ -45,7 +45,7 @@ static void start_dbus_daemon(void)
char *prg_envp[1];
pid_t pid;
- prg_argv[0] = "/usr/bin/dbus-daemon";
+ prg_argv[0] = "dbus-daemon";
prg_argv[1] = "--nopidfile";
prg_argv[2] = "--nofork";
prg_argv[3] = "--config-file=" UNITDIR "dbus.conf";
@@ -62,7 +62,7 @@ static void start_dbus_daemon(void)
}
if (pid == 0) {
- execve(prg_argv[0], prg_argv, prg_envp);
+ execvpe(prg_argv[0], prg_argv, prg_envp);
exit(EXIT_SUCCESS);
}
--
2.29.2
1 year, 5 months
[PATCH 1/8] pem: Move PKCS private key parsing to cert.c
by Andrew Zaborowski
This code implements the parsing and building of ASN.1 structures
defined in PKCS and RFCs that say nothing about encoding them as PEM, in
fact the PKCS#8 private key structures are also used in binary file
formats. The legacy encrypted PKCS#1 RSAPrivateKey format is probably
only used in PEM files since it depends on the non-standard PEM headers,
so leave the decoding in pem.c.
---
ell/cert-private.h | 8 +++
ell/cert.c | 163 +++++++++++++++++++++++++++++++++++++++++++++
ell/pem-private.h | 7 --
ell/pem.c | 160 +-------------------------------------------
4 files changed, 174 insertions(+), 164 deletions(-)
diff --git a/ell/cert-private.h b/ell/cert-private.h
index 929f88d..e792c4c 100644
--- a/ell/cert-private.h
+++ b/ell/cert-private.h
@@ -28,3 +28,11 @@ void certchain_link_issuer(struct l_certchain *chain, struct l_cert *ca);
const uint8_t *cert_get_extension(struct l_cert *cert,
const struct asn1_oid *ext_id,
bool *out_critical, size_t *out_len);
+
+struct l_key *cert_key_from_pkcs8_private_key_info(const uint8_t *der,
+ size_t der_len);
+struct l_key *cert_key_from_pkcs8_encrypted_private_key_info(const uint8_t *der,
+ size_t der_len,
+ const char *passphrase);
+struct l_key *cert_key_from_pkcs1_rsa_private_key(const uint8_t *der,
+ size_t der_len);
diff --git a/ell/cert.c b/ell/cert.c
index cfe9a8d..a102fcc 100644
--- a/ell/cert.c
+++ b/ell/cert.c
@@ -29,6 +29,9 @@
#include "key.h"
#include "queue.h"
#include "asn1-private.h"
+#include "cipher.h"
+#include "pkcs5.h"
+#include "pkcs5-private.h"
#include "cert.h"
#include "cert-private.h"
@@ -576,3 +579,163 @@ LIB_EXPORT bool l_certchain_verify(struct l_certchain *chain,
l_key_free(prev_key);
return true;
}
+
+struct l_key *cert_key_from_pkcs8_private_key_info(const uint8_t *der,
+ size_t der_len)
+{
+ return l_key_new(L_KEY_RSA, der, der_len);
+}
+
+struct l_key *cert_key_from_pkcs8_encrypted_private_key_info(const uint8_t *der,
+ size_t der_len,
+ const char *passphrase)
+{
+ const uint8_t *key_info, *alg_id, *data;
+ uint8_t tag;
+ size_t key_info_len, alg_id_len, data_len, tmp_len;
+ struct l_cipher *alg;
+ uint8_t *decrypted;
+ int i;
+ struct l_key *pkey;
+ bool r;
+ bool is_block;
+ size_t decrypted_len;
+
+ /* Technically this is BER, not limited to DER */
+ key_info = asn1_der_find_elem(der, der_len, 0, &tag, &key_info_len);
+ if (!key_info || tag != ASN1_ID_SEQUENCE)
+ return NULL;
+
+ alg_id = asn1_der_find_elem(key_info, key_info_len, 0, &tag,
+ &alg_id_len);
+ if (!alg_id || tag != ASN1_ID_SEQUENCE)
+ return NULL;
+
+ data = asn1_der_find_elem(key_info, key_info_len, 1, &tag, &data_len);
+ if (!data || tag != ASN1_ID_OCTET_STRING || data_len < 8 ||
+ (data_len & 7) != 0)
+ return NULL;
+
+ if (asn1_der_find_elem(der, der_len, 2, &tag, &tmp_len))
+ return NULL;
+
+ alg = pkcs5_cipher_from_alg_id(alg_id, alg_id_len, passphrase,
+ &is_block);
+ if (!alg)
+ return NULL;
+
+ decrypted = l_malloc(data_len);
+
+ r = l_cipher_decrypt(alg, data, decrypted, data_len);
+ l_cipher_free(alg);
+
+ if (!r) {
+ l_free(decrypted);
+ return NULL;
+ }
+
+ decrypted_len = data_len;
+
+ if (is_block) {
+ /*
+ * For block ciphers strip padding as defined in RFC8018
+ * (for PKCS#5 v1) or RFC1423 / RFC5652 (for v2).
+ */
+ pkey = NULL;
+
+ if (decrypted[data_len - 1] >= data_len ||
+ decrypted[data_len - 1] > 16)
+ goto cleanup;
+
+ for (i = 1; i < decrypted[data_len - 1]; i++)
+ if (decrypted[data_len - 1 - i] !=
+ decrypted[data_len - 1])
+ goto cleanup;
+
+ decrypted_len -= decrypted[data_len - 1];
+ }
+
+ pkey = cert_key_from_pkcs8_private_key_info(decrypted, decrypted_len);
+
+cleanup:
+ explicit_bzero(decrypted, data_len);
+ l_free(decrypted);
+ return pkey;
+}
+
+struct l_key *cert_key_from_pkcs1_rsa_private_key(const uint8_t *der,
+ size_t der_len)
+{
+ 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;
+ struct l_key *pkey;
+
+ 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.
+ */
+ key_data = asn1_der_find_elem(der, der_len, 0, &tag, &key_data_len);
+ if (!key_data || tag != ASN1_ID_SEQUENCE)
+ return NULL;
+
+ 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))
+ return NULL;
+
+ 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)
+ return NULL;
+ }
+
+ private_key = l_malloc(10 + der_len);
+ ptr = private_key;
+ *ptr++ = ASN1_ID_OCTET_STRING;
+ asn1_write_definite_length(&ptr, der_len);
+ memcpy(ptr, der, der_len);
+ ptr += der_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;
+ explicit_bzero(private_key, private_key_len);
+ l_free(private_key);
+
+ pkey = cert_key_from_pkcs8_private_key_info(one_asymmetric_key,
+ ptr - one_asymmetric_key);
+ explicit_bzero(one_asymmetric_key, ptr - one_asymmetric_key);
+ l_free(one_asymmetric_key);
+
+ return pkey;
+}
diff --git a/ell/pem-private.h b/ell/pem-private.h
index 10f918f..68e3fcb 100644
--- a/ell/pem-private.h
+++ b/ell/pem-private.h
@@ -33,12 +33,5 @@ const char *pem_next(const void *buf, size_t buf_len, char **type_label,
size_t *base64_len,
const char **endp, bool strict);
-struct l_key *pem_key_from_pkcs8_private_key_info(const uint8_t *der,
- size_t der_len);
-
-struct l_key *pem_key_from_pkcs8_encrypted_private_key_info(const uint8_t *der,
- size_t der_len,
- const char *passphrase);
-
int pem_write_certificate_chain(const struct l_certchain *cert,
const char *filename);
diff --git a/ell/pem.c b/ell/pem.c
index fd25016..384fb9f 100644
--- a/ell/pem.c
+++ b/ell/pem.c
@@ -41,7 +41,6 @@
#include "base64.h"
#include "utf8.h"
#include "asn1-private.h"
-#include "pkcs5-private.h"
#include "cipher.h"
#include "cert-private.h"
#include "missing.h"
@@ -646,89 +645,6 @@ cleanup:
return cipher;
}
-struct l_key *pem_key_from_pkcs8_private_key_info(const uint8_t *der,
- size_t der_len)
-{
- return l_key_new(L_KEY_RSA, der, der_len);
-}
-
-struct l_key *pem_key_from_pkcs8_encrypted_private_key_info(const uint8_t *der,
- size_t der_len,
- const char *passphrase)
-{
- const uint8_t *key_info, *alg_id, *data;
- uint8_t tag;
- size_t key_info_len, alg_id_len, data_len, tmp_len;
- struct l_cipher *alg;
- uint8_t *decrypted;
- int i;
- struct l_key *pkey;
- bool r;
- bool is_block;
- size_t decrypted_len;
-
- /* Technically this is BER, not limited to DER */
- key_info = asn1_der_find_elem(der, der_len, 0, &tag, &key_info_len);
- if (!key_info || tag != ASN1_ID_SEQUENCE)
- return NULL;
-
- alg_id = asn1_der_find_elem(key_info, key_info_len, 0, &tag,
- &alg_id_len);
- if (!alg_id || tag != ASN1_ID_SEQUENCE)
- return NULL;
-
- data = asn1_der_find_elem(key_info, key_info_len, 1, &tag, &data_len);
- if (!data || tag != ASN1_ID_OCTET_STRING || data_len < 8 ||
- (data_len & 7) != 0)
- return NULL;
-
- if (asn1_der_find_elem(der, der_len, 2, &tag, &tmp_len))
- return NULL;
-
- alg = pkcs5_cipher_from_alg_id(alg_id, alg_id_len, passphrase,
- &is_block);
- if (!alg)
- return NULL;
-
- decrypted = l_malloc(data_len);
-
- r = l_cipher_decrypt(alg, data, decrypted, data_len);
- l_cipher_free(alg);
-
- if (!r) {
- l_free(decrypted);
- return NULL;
- }
-
- decrypted_len = data_len;
-
- if (is_block) {
- /*
- * For block ciphers strip padding as defined in RFC8018
- * (for PKCS#5 v1) or RFC1423 / RFC5652 (for v2).
- */
- pkey = NULL;
-
- if (decrypted[data_len - 1] >= data_len ||
- decrypted[data_len - 1] > 16)
- goto cleanup;
-
- for (i = 1; i < decrypted[data_len - 1]; i++)
- if (decrypted[data_len - 1 - i] !=
- decrypted[data_len - 1])
- goto cleanup;
-
- decrypted_len -= decrypted[data_len - 1];
- }
-
- pkey = pem_key_from_pkcs8_private_key_info(decrypted, decrypted_len);
-
-cleanup:
- explicit_bzero(decrypted, data_len);
- l_free(decrypted);
- return pkey;
-}
-
static struct l_key *pem_load_private_key(uint8_t *content,
size_t len,
char *label,
@@ -749,7 +665,7 @@ static struct l_key *pem_load_private_key(uint8_t *content,
if (headers)
goto err;
- pkey = pem_key_from_pkcs8_private_key_info(content, len);
+ pkey = cert_key_from_pkcs8_private_key_info(content, len);
goto done;
}
@@ -771,7 +687,7 @@ static struct l_key *pem_load_private_key(uint8_t *content,
if (headers)
goto err;
- pkey = pem_key_from_pkcs8_encrypted_private_key_info(content,
+ pkey = cert_key_from_pkcs8_encrypted_private_key_info(content,
len,
passphrase);
goto done;
@@ -784,29 +700,9 @@ static struct l_key *pem_load_private_key(uint8_t *content,
* PrivateKeyInfo for the pkcs8-key-parser module.
*/
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;
const char *dekalgid;
const char *dekparameters;
- 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,
- };
-
/*
* "openssl rsa ..." can produce encrypted PKCS#1-formatted
* keys. These are incompatible with RFC7468 parsing because
@@ -855,57 +751,7 @@ static struct l_key *pem_load_private_key(uint8_t *content,
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
- * 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 err;
-
- 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 err;
-
- 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 err;
- }
-
- 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;
- explicit_bzero(private_key, private_key_len);
- l_free(private_key);
-
- pkey = pem_key_from_pkcs8_private_key_info(one_asymmetric_key,
- ptr - one_asymmetric_key);
- explicit_bzero(one_asymmetric_key, ptr - one_asymmetric_key);
- l_free(one_asymmetric_key);
+ pkey = cert_key_from_pkcs1_rsa_private_key(content, len);
goto done;
}
--
2.27.0
1 year, 6 months
[PATCH 1/3] pem: Add pem_write_certificate_chain
by Andrew Zaborowski
---
ell/pem-private.h | 5 +++++
ell/pem.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/ell/pem-private.h b/ell/pem-private.h
index 6e9458d..10f918f 100644
--- a/ell/pem-private.h
+++ b/ell/pem-private.h
@@ -27,6 +27,8 @@
#define _GNU_SOURCE
#include <sys/types.h>
+struct l_certchain;
+
const char *pem_next(const void *buf, size_t buf_len, char **type_label,
size_t *base64_len,
const char **endp, bool strict);
@@ -37,3 +39,6 @@ struct l_key *pem_key_from_pkcs8_private_key_info(const uint8_t *der,
struct l_key *pem_key_from_pkcs8_encrypted_private_key_info(const uint8_t *der,
size_t der_len,
const char *passphrase);
+
+int pem_write_certificate_chain(const struct l_certchain *cert,
+ const char *filename);
diff --git a/ell/pem.c b/ell/pem.c
index 1b995d5..fd25016 100644
--- a/ell/pem.c
+++ b/ell/pem.c
@@ -364,6 +364,51 @@ LIB_EXPORT struct l_certchain *l_pem_load_certificate_chain(
return pem_list_to_chain(list);
}
+static bool pem_write_one_cert(struct l_cert *cert, void *user_data)
+{
+ int *fd = user_data;
+ const uint8_t *der;
+ size_t der_len;
+ struct iovec iov[3];
+ ssize_t r;
+
+ der = l_cert_get_der_data(cert, &der_len);
+
+ iov[0].iov_base = "-----BEGIN CERTIFICATE-----\n";
+ iov[0].iov_len = strlen(iov[0].iov_base);
+ iov[1].iov_base = l_base64_encode(der, der_len, 64, &iov[1].iov_len);
+ iov[2].iov_base = "\n-----END CERTIFICATE-----\n";
+ iov[2].iov_len = strlen(iov[2].iov_base);
+ r = L_TFR(writev(*fd, iov, 3));
+ l_free(iov[1].iov_base);
+
+ if (r == (ssize_t) (iov[0].iov_len + iov[1].iov_len + iov[2].iov_len))
+ return false;
+
+ if (r < 0)
+ *fd = -errno;
+ else
+ *fd = -EIO;
+
+ return true;
+}
+
+int pem_write_certificate_chain(const struct l_certchain *chain,
+ const char *filename)
+{
+ int fd = L_TFR(open(filename, O_CREAT | O_WRONLY | O_CLOEXEC, 0600));
+ int err = fd;
+
+ if (err < 0)
+ return -errno;
+
+ l_certchain_walk_from_leaf((struct l_certchain *) chain,
+ pem_write_one_cert, &err);
+ close(fd);
+
+ return err < 0 ? err : 0;
+}
+
LIB_EXPORT struct l_queue *l_pem_load_certificate_list_from_data(
const void *buf, size_t len)
{
--
2.27.0
1 year, 6 months
[PATCH 1/4] tls: Print only one tls_cert_domains_match_mask debug msg
by Andrew Zaborowski
Change tls_cert_domains_match_mask to compile one error message string
instead of printing messages at different step. The rest of the TLS debug
log tries to be concise when there's no errors so try to be concise here
too.
---
This is the tls_cert_domains_match_mask version I had in my tree and
thought I might just send it.
ell/tls.c | 71 +++++++++++++++++++++++++++++++++++--------------------
1 file changed, 45 insertions(+), 26 deletions(-)
diff --git a/ell/tls.c b/ell/tls.c
index 5bf6573..1452909 100644
--- a/ell/tls.c
+++ b/ell/tls.c
@@ -679,8 +679,8 @@ static const struct asn1_oid dn_common_name_oid =
#define SAN_DNS_NAME_ID ASN1_CONTEXT_IMPLICIT(2)
-static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
- char **mask)
+static bool tls_cert_domains_match_mask(struct l_cert *cert, char **mask,
+ char **error_msg)
{
const uint8_t *san, *dn, *end;
size_t san_len, dn_len;
@@ -688,7 +688,8 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
const char *cn = NULL;
size_t cn_len;
char **i;
- bool dns_name_present = false;
+ struct l_string *dns_names = NULL;
+ int dns_name_count = 0;
/*
* Locate SubjectAltName (RFC5280 Section 4.2.1.6) and descend into
@@ -698,7 +699,7 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
if (san) {
san = asn1_der_find_elem(san, san_len, 0, &san_tag, &san_len);
if (unlikely(!san || san_tag != ASN1_ID_SEQUENCE))
- return false;
+ goto parse_error;
end = san + san_len;
while (san < end) {
@@ -714,18 +715,26 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
/* Type is implicitly IA5STRING */
- for (i = mask; *i; i++) {
- TLS_DEBUG("Trying to match DNSName: '%.*s'"
- " against mask: '%s'",
- (int) len, value, *i);
-
+ for (i = mask; *i; i++)
if (tls_domain_match_mask((const char *) value,
- len, *i, strlen(*i)))
+ len, *i, strlen(*i))) {
+ l_string_free(dns_names);
return true;
+ }
+
+ if (!dns_names) {
+ dns_names = l_string_new(128);
+ l_string_append(dns_names, "tried DNSName(s) ");
+ l_string_append_fixed(dns_names,
+ (char *) value, len);
+ } else if (dns_name_count < 20) {
+ l_string_append(dns_names, ", ");
+ l_string_append_fixed(dns_names,
+ (char *) value, len);
}
san = value + len;
- dns_name_present = true;
+ dns_name_count++;
}
}
@@ -744,12 +753,17 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
* SubjectName. If neither of these conditions holds, then
* verification fails."
*/
- if (unlikely(dns_name_present))
- return false;
+ if (dns_name_count) {
+ if (dns_name_count > 20)
+ l_string_append_printf(dns_names, " and %i other",
+ dns_name_count - 20);
+
+ *error_msg = l_string_unwrap(dns_names);
+ }
dn = l_cert_get_dn(cert, &dn_len);
if (unlikely(!dn))
- return false;
+ goto parse_error;
end = dn + dn_len;
while (dn < end) {
@@ -759,17 +773,17 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
set = asn1_der_find_elem(dn, end - dn, 0, &tag, &len);
if (unlikely(!set || tag != ASN1_ID_SET))
- return false;
+ goto parse_error;
dn = set + len;
seq = asn1_der_find_elem(set, len, 0, &tag, &len);
if (unlikely(!seq || tag != ASN1_ID_SEQUENCE))
- return false;
+ goto parse_error;
oid = asn1_der_find_elem(seq, len, 0, &tag, &oid_len);
if (unlikely(!oid || tag != ASN1_ID_OID))
- return false;
+ goto parse_error;
name = asn1_der_find_elem(seq, len, 1, &tag, &name_len);
if (unlikely(!name || (tag != ASN1_ID_PRINTABLESTRING &&
@@ -785,15 +799,17 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
}
if (unlikely(!cn))
- return false;
-
- for (i = mask; *i; i++) {
- TLS_DEBUG("Trying to match CN: '%.*s' against mask: '%s'",
- (int) cn_len, cn, *i);
+ goto parse_error;
+ for (i = mask; *i; i++)
if (tls_domain_match_mask(cn, cn_len, *i, strlen(*i)))
return true;
- }
+
+ *error_msg = l_strdup_printf("tried CommonName %.*s", (int) cn_len, cn);
+ return false;
+
+parse_error:
+ *error_msg = l_strdup("couldn't locate DNSName or CommonName");
return false;
}
@@ -1886,6 +1902,7 @@ static void tls_handle_certificate(struct l_tls *tls,
const uint8_t *der;
bool dummy;
const char *error_str;
+ char *subject_str;
if (len < 3)
goto decode_error;
@@ -1955,14 +1972,16 @@ static void tls_handle_certificate(struct l_tls *tls,
goto done;
}
- if (tls->subject_mask && !tls_cert_domains_match_mask(tls, leaf,
- tls->subject_mask)) {
+ if (tls->subject_mask && !tls_cert_domains_match_mask(leaf,
+ tls->subject_mask,
+ &subject_str)) {
char *mask = l_strjoinv(tls->subject_mask, '|');
TLS_DISCONNECT(TLS_ALERT_BAD_CERT, 0,
"Peer certificate's subject domain "
- "doesn't match %s", mask);
+ "doesn't match mask %s: %s", mask, subject_str);
l_free(mask);
+ l_free(subject_str);
goto done;
}
--
2.27.0
1 year, 6 months
[PATCH 1/5] tls: Print only one tls_cert_domains_match_mask debug msg
by Andrew Zaborowski
Change tls_cert_domains_match_mask to compile one error message string
instead of printing messages at different step. The rest of the TLS debug
log tries to be concise when there's no errors so try to be concise here
too.
---
This is the tls_cert_domains_match_mask version I had in my tree and
thought I might just send it.
---
ell/tls.c | 71 +++++++++++++++++++++++++++++++++++--------------------
1 file changed, 45 insertions(+), 26 deletions(-)
diff --git a/ell/tls.c b/ell/tls.c
index 5bf6573..1452909 100644
--- a/ell/tls.c
+++ b/ell/tls.c
@@ -679,8 +679,8 @@ static const struct asn1_oid dn_common_name_oid =
#define SAN_DNS_NAME_ID ASN1_CONTEXT_IMPLICIT(2)
-static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
- char **mask)
+static bool tls_cert_domains_match_mask(struct l_cert *cert, char **mask,
+ char **error_msg)
{
const uint8_t *san, *dn, *end;
size_t san_len, dn_len;
@@ -688,7 +688,8 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
const char *cn = NULL;
size_t cn_len;
char **i;
- bool dns_name_present = false;
+ struct l_string *dns_names = NULL;
+ int dns_name_count = 0;
/*
* Locate SubjectAltName (RFC5280 Section 4.2.1.6) and descend into
@@ -698,7 +699,7 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
if (san) {
san = asn1_der_find_elem(san, san_len, 0, &san_tag, &san_len);
if (unlikely(!san || san_tag != ASN1_ID_SEQUENCE))
- return false;
+ goto parse_error;
end = san + san_len;
while (san < end) {
@@ -714,18 +715,26 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
/* Type is implicitly IA5STRING */
- for (i = mask; *i; i++) {
- TLS_DEBUG("Trying to match DNSName: '%.*s'"
- " against mask: '%s'",
- (int) len, value, *i);
-
+ for (i = mask; *i; i++)
if (tls_domain_match_mask((const char *) value,
- len, *i, strlen(*i)))
+ len, *i, strlen(*i))) {
+ l_string_free(dns_names);
return true;
+ }
+
+ if (!dns_names) {
+ dns_names = l_string_new(128);
+ l_string_append(dns_names, "tried DNSName(s) ");
+ l_string_append_fixed(dns_names,
+ (char *) value, len);
+ } else if (dns_name_count < 20) {
+ l_string_append(dns_names, ", ");
+ l_string_append_fixed(dns_names,
+ (char *) value, len);
}
san = value + len;
- dns_name_present = true;
+ dns_name_count++;
}
}
@@ -744,12 +753,17 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
* SubjectName. If neither of these conditions holds, then
* verification fails."
*/
- if (unlikely(dns_name_present))
- return false;
+ if (dns_name_count) {
+ if (dns_name_count > 20)
+ l_string_append_printf(dns_names, " and %i other",
+ dns_name_count - 20);
+
+ *error_msg = l_string_unwrap(dns_names);
+ }
dn = l_cert_get_dn(cert, &dn_len);
if (unlikely(!dn))
- return false;
+ goto parse_error;
end = dn + dn_len;
while (dn < end) {
@@ -759,17 +773,17 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
set = asn1_der_find_elem(dn, end - dn, 0, &tag, &len);
if (unlikely(!set || tag != ASN1_ID_SET))
- return false;
+ goto parse_error;
dn = set + len;
seq = asn1_der_find_elem(set, len, 0, &tag, &len);
if (unlikely(!seq || tag != ASN1_ID_SEQUENCE))
- return false;
+ goto parse_error;
oid = asn1_der_find_elem(seq, len, 0, &tag, &oid_len);
if (unlikely(!oid || tag != ASN1_ID_OID))
- return false;
+ goto parse_error;
name = asn1_der_find_elem(seq, len, 1, &tag, &name_len);
if (unlikely(!name || (tag != ASN1_ID_PRINTABLESTRING &&
@@ -785,15 +799,17 @@ static bool tls_cert_domains_match_mask(struct l_tls *tls, struct l_cert *cert,
}
if (unlikely(!cn))
- return false;
-
- for (i = mask; *i; i++) {
- TLS_DEBUG("Trying to match CN: '%.*s' against mask: '%s'",
- (int) cn_len, cn, *i);
+ goto parse_error;
+ for (i = mask; *i; i++)
if (tls_domain_match_mask(cn, cn_len, *i, strlen(*i)))
return true;
- }
+
+ *error_msg = l_strdup_printf("tried CommonName %.*s", (int) cn_len, cn);
+ return false;
+
+parse_error:
+ *error_msg = l_strdup("couldn't locate DNSName or CommonName");
return false;
}
@@ -1886,6 +1902,7 @@ static void tls_handle_certificate(struct l_tls *tls,
const uint8_t *der;
bool dummy;
const char *error_str;
+ char *subject_str;
if (len < 3)
goto decode_error;
@@ -1955,14 +1972,16 @@ static void tls_handle_certificate(struct l_tls *tls,
goto done;
}
- if (tls->subject_mask && !tls_cert_domains_match_mask(tls, leaf,
- tls->subject_mask)) {
+ if (tls->subject_mask && !tls_cert_domains_match_mask(leaf,
+ tls->subject_mask,
+ &subject_str)) {
char *mask = l_strjoinv(tls->subject_mask, '|');
TLS_DISCONNECT(TLS_ALERT_BAD_CERT, 0,
"Peer certificate's subject domain "
- "doesn't match %s", mask);
+ "doesn't match mask %s: %s", mask, subject_str);
l_free(mask);
+ l_free(subject_str);
goto done;
}
--
2.27.0
1 year, 6 months
[PATCH 1/5] pkcs5: Add the PKCS#12 KDF
by Andrew Zaborowski
Add the key derivation algorithm used with PKCS#12 to pkcs5.c so that it
can be found together with the two PKCS#5 KDFs, and so that it can also
be used when parsing of the PKCS#12 AlgorithmIdentifiers in the next
commit. This KDF is not recommended for new uses.
---
ell/pkcs5-private.h | 12 +++++
ell/pkcs5.c | 121 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 133 insertions(+)
diff --git a/ell/pkcs5-private.h b/ell/pkcs5-private.h
index 27ff41c..9b85fdd 100644
--- a/ell/pkcs5-private.h
+++ b/ell/pkcs5-private.h
@@ -20,6 +20,18 @@
*
*/
+struct pkcs12_hash {
+ enum l_checksum_type alg;
+ unsigned int len;
+ unsigned int u;
+ unsigned int v;
+ struct asn1_oid oid;
+};
+
+uint8_t *pkcs12_pbkdf(const char *password, const struct pkcs12_hash *hash,
+ const uint8_t *salt, size_t salt_len,
+ unsigned int iterations, uint8_t id, size_t key_len);
+
struct l_cipher *pkcs5_cipher_from_alg_id(const uint8_t *id_asn1,
size_t id_asn1_len,
const char *password,
diff --git a/ell/pkcs5.c b/ell/pkcs5.c
index 21fda2b..979cebe 100644
--- a/ell/pkcs5.c
+++ b/ell/pkcs5.c
@@ -33,6 +33,7 @@
#include "checksum.h"
#include "cipher.h"
#include "util.h"
+#include "utf8.h"
#include "asn1-private.h"
#include "pkcs5.h"
#include "pkcs5-private.h"
@@ -182,14 +183,134 @@ LIB_EXPORT bool l_pkcs5_pbkdf2(enum l_checksum_type type, const char *password,
return !dk_len;
}
+/* RFC7292 Appendix B */
+uint8_t *pkcs12_pbkdf(const char *password, const struct pkcs12_hash *hash,
+ const uint8_t *salt, size_t salt_len,
+ unsigned int iterations, uint8_t id, size_t key_len)
+{
+ /* All lengths in bytes instead of bits */
+ size_t passwd_len = password ? 2 * strlen(password) + 2 : 0;
+ uint8_t *bmpstring;
+ /* Documented as v(ceiling(s/v)), usually will just equal v */
+ unsigned int s_len = (salt_len + hash->v - 1) & ~(hash->v - 1);
+ /* Documented as p(ceiling(s/p)), usually will just equal v */
+ unsigned int p_len = (passwd_len + hash->v - 1) & ~(hash->v - 1);
+ uint8_t di[hash->v + s_len + p_len];
+ uint8_t *ptr;
+ unsigned int j;
+ uint8_t *key;
+ unsigned int bytes;
+ struct l_checksum *h = l_checksum_new(hash->alg);
+
+ if (!h)
+ return NULL;
+
+ /*
+ * The BMPString encoding, in practice same as UCS-2, can end up
+ * at 2 * strlen(password) + 2 bytes or shorter depending on the
+ * characters used. Recalculate p_len after we know it.
+ * Important: The password must be valid UTF-8 here.
+ */
+ if (password) {
+ if (!(bmpstring = l_utf8_to_ucs2be(password, &passwd_len))) {
+ l_checksum_free(h);
+ return NULL;
+ }
+
+ p_len = (passwd_len + hash->v - 1) & ~(hash->v - 1);
+ }
+
+ memset(di, id, hash->v);
+ ptr = di + hash->v;
+
+ for (j = salt_len; j < s_len; j += salt_len, ptr += salt_len)
+ memcpy(ptr, salt, salt_len);
+
+ if (s_len) {
+ memcpy(ptr, salt, s_len + salt_len - j);
+ ptr += s_len + salt_len - j;
+ }
+
+ for (j = passwd_len; j < p_len; j += passwd_len, ptr += passwd_len)
+ memcpy(ptr, bmpstring, passwd_len);
+
+ if (p_len) {
+ memcpy(ptr, bmpstring, p_len + passwd_len - j);
+
+ explicit_bzero(bmpstring, passwd_len);
+ l_free(bmpstring);
+ }
+
+ key = l_malloc(key_len + hash->len);
+
+ for (bytes = 0; bytes < key_len; bytes += hash->u) {
+ uint8_t b[hash->v];
+ uint8_t *input = di;
+ unsigned int input_len = hash->v + s_len + p_len;
+
+ for (j = 0; j < iterations; j++) {
+ if (!l_checksum_update(h, input, input_len) ||
+ l_checksum_get_digest(h,
+ key + bytes,
+ hash->len) <= 0) {
+ l_checksum_free(h);
+ l_free(key);
+ return NULL;
+ }
+
+ input = key + bytes;
+ input_len = hash->u;
+ l_checksum_reset(h);
+ }
+
+ if (bytes + hash->u >= key_len)
+ break;
+
+ for (j = 0; j < hash->v - hash->u; j += hash->u)
+ memcpy(b + j, input, hash->u);
+
+ memcpy(b + j, input, hash->v - j);
+
+ ptr = di + hash->v;
+ for (j = 0; j < s_len + p_len; j += hash->v, ptr += hash->v) {
+ unsigned int k;
+ uint16_t carry = 1;
+
+ /*
+ * Not specified in the RFC7292 but implementations
+ * sum these octet strings as big-endian integers.
+ * We could use 64-bit additions here but the benefit
+ * may not compensate the cost of the byteswapping.
+ */
+ for (k = hash->v - 1; k > 0; k--) {
+ carry = ptr[k] + b[k] + carry;
+ ptr[k] = carry;
+ carry >>= 8;
+ }
+
+ ptr[k] += b[k] + carry;
+ explicit_bzero(&carry, sizeof(carry));
+ }
+
+ explicit_bzero(b, sizeof(b));
+ }
+
+ explicit_bzero(di, sizeof(di));
+ l_checksum_free(h);
+ return key;
+}
+
+/* RFC8018 Section A.2 */
static struct asn1_oid pkcs5_pbkdf2_oid = {
9, { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c }
};
+/* RFC8018 Section A.4 */
static struct asn1_oid pkcs5_pbes2_oid = {
9, { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0d }
};
+/* RFC8018 Section A.3 */
static const struct pkcs5_pbes1_encryption_oid {
enum l_checksum_type checksum_type;
enum l_cipher_type cipher_type;
--
2.27.0
1 year, 6 months
[PATCH 1/2] dhcp: add ACD to DHCP client
by James Prestwood
This starts the ACD client once DHCP binds to an address.
The ACD client is (for now) configured to defend its address
infinitely. This maintains existing behavior except that
ACD announcements are now sent if conflicts are detected.
---
ell/dhcp.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/ell/dhcp.c b/ell/dhcp.c
index e104845..f212e9b 100644
--- a/ell/dhcp.c
+++ b/ell/dhcp.c
@@ -41,6 +41,7 @@
#include "dhcp-private.h"
#include "netlink.h"
#include "rtnl.h"
+#include "acd.h"
#define CLIENT_DEBUG(fmt, args...) \
l_util_debug(client->debug_handler, client->debug_data, \
@@ -190,6 +191,7 @@ struct l_dhcp_client {
l_dhcp_destroy_cb_t event_destroy;
l_dhcp_debug_cb_t debug_handler;
l_dhcp_destroy_cb_t debug_destroy;
+ struct l_acd *acd;
void *debug_data;
bool have_addr : 1;
bool override_xid : 1;
@@ -777,6 +779,7 @@ static void dhcp_client_rx_message(const void *data, size_t len, void *userdata)
uint8_t t, l;
const void *v;
int r;
+ struct in_addr ia;
CLIENT_DEBUG("");
@@ -877,6 +880,41 @@ static void dhcp_client_rx_message(const void *data, size_t len, void *userdata)
dhcp_client_t1_expired,
client, NULL);
}
+
+ /* ACD is already running, no need to re-announce */
+ if (client->acd)
+ break;
+
+ client->acd = l_acd_new(client->ifindex);
+
+ if (client->debug_handler)
+ l_acd_set_debug(client->acd, client->debug_handler,
+ client->debug_data,
+ client->debug_destroy);
+
+ /*
+ * TODO: There is no mechanism yet to deal with IPs leased by
+ * the DHCP server which conflict with other devices. For now
+ * the ACD object is being initialized to defend infinitely
+ * which is effectively no different than the non-ACD behavior
+ * (ignore conflicts and continue using address). The only
+ * change is that announcements will be sent if conflicts are
+ * found.
+ */
+ l_acd_set_defend_policy(client->acd,
+ L_ACD_DEFEND_POLICY_INFINITE);
+ l_acd_set_skip_probes(client->acd, true);
+
+ ia.s_addr = client->lease->address;
+
+ /* For unit testing we don't want this to be a fatal error */
+ if (!l_acd_start(client->acd, inet_ntoa(ia))) {
+ CLIENT_DEBUG("Failed to start ACD on %s, continuing",
+ inet_ntoa(ia));
+ l_acd_destroy(client->acd);
+ client->acd = NULL;
+ }
+
break;
case DHCP_STATE_INIT_REBOOT:
case DHCP_STATE_REBOOTING:
@@ -1156,6 +1194,11 @@ LIB_EXPORT bool l_dhcp_client_stop(struct l_dhcp_client *client)
_dhcp_lease_free(client->lease);
client->lease = NULL;
+ if (client->acd) {
+ l_acd_destroy(client->acd);
+ client->acd = NULL;
+ }
+
return true;
}
--
2.26.2
1 year, 6 months
[PATCH 01/13] pem: Wipe more memory in PKCS#1 private key decoding
by Andrew Zaborowski
bzero some more potentially sensitive memory that we weren't bzeroing in
the recently added openssl legacy PKCS#1 private key format decoding.
---
ell/pem.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/ell/pem.c b/ell/pem.c
index 790f2c2..70d1f62 100644
--- a/ell/pem.c
+++ b/ell/pem.c
@@ -581,18 +581,24 @@ static struct l_cipher *cipher_from_dek_info(const char *algid, const char *para
l_checksum_free(md5);
- if (!ok)
- return NULL;
+ if (!ok) {
+ cipher = NULL;
+ goto cleanup;
+ }
cipher = l_cipher_new(type, key, key_len);
if (!cipher)
- return NULL;
+ goto cleanup;
if (l_cipher_set_iv(cipher, iv, iv_len))
- return cipher;
+ goto cleanup;
l_cipher_free(cipher);
- return NULL;
+ cipher = NULL;
+
+cleanup:
+ explicit_bzero(key, sizeof(key));
+ return cipher;
}
static struct l_key *pem_load_private_key(uint8_t *content,
@@ -821,8 +827,10 @@ static struct l_key *pem_load_private_key(uint8_t *content,
ptr += sizeof(pkcs1_rsa_encryption);
memcpy(ptr, private_key, private_key_len);
ptr += private_key_len;
+ explicit_bzero(private_key, private_key_len);
l_free(private_key);
+ explicit_bzero(content, len);
l_free(content);
content = one_asymmetric_key;
len = ptr - one_asymmetric_key;
--
2.27.0
1 year, 6 months
[PATCH 10/13] build: Add more test certificates in various formats
by Andrew Zaborowski
Add a binary X.509 test certificate and PKCS#12 files using various
cipher combinations.
---
Makefile.am | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index 28082aa..66c08c1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -213,6 +213,7 @@ cert_files = unit/cert-chain.pem \
unit/cert-server.pem \
unit/cert-server-key-pkcs8.pem \
unit/cert-client.pem \
+ unit/cert-client.crt \
unit/cert-client-key-pkcs1.pem \
unit/cert-client-key-pkcs1-des.pem \
unit/cert-client-key-pkcs1-des3.pem \
@@ -226,6 +227,12 @@ cert_files = unit/cert-chain.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-entity-pkcs12-nomac.p12 \
+ unit/cert-entity-pkcs12-rc2-sha1.p12 \
+ unit/cert-entity-pkcs12-des-sha256.p12 \
+ unit/cert-entity-pkcs12-rc4-sha384.p12 \
+ unit/cert-entity-pkcs12-pkcs5-sha512.p12 \
+ unit/cert-entity-combined.pem \
unit/cert-no-keyid.pem
cert_checks = unit/cert-intca \
@@ -484,6 +491,9 @@ unit/cert-client.pem: unit/cert-client.csr unit/cert-ca.pem unit/gencerts.cnf
unit/cert-client: unit/cert-client.pem unit/cert-ca.pem
$(AM_V_GEN)openssl verify -CAfile $(builddir)/unit/cert-ca.pem $<
+unit/cert-client.crt: unit/cert-client.pem
+ $(AM_V_GEN)openssl x509 -in $< -out $@ -outform der
+
unit/cert-intca-key.pem:
$(AM_V_GEN)openssl genrsa -out $@ $($(AM_V_P)_redirect_openssl)
@@ -550,6 +560,24 @@ unit/cert-no-keyid.pem: unit/cert-no-keyid.csr unit/cert-ca2.pem unit/gencerts.c
unit/cert-no-keyid: unit/cert-no-keyid.pem unit/cert-ca2.pem
$(AM_V_GEN)openssl verify -CAfile $(builddir)/unit/cert-ca2.pem $<
+unit/cert-entity-pkcs12-nomac.p12: unit/cert-entity-int-key.pem unit/cert-entity-int.pem
+ $(AM_V_GEN)openssl pkcs12 -inkey $< -in $(builddir)/unit/cert-entity-int.pem -out $@ -export -passout pass:abc -nomac # defaut ciphers
+
+unit/cert-entity-pkcs12-rc2-sha1.p12: unit/cert-entity-int-key.pem unit/cert-entity-int.pem unit/cert-chain.pem
+ $(AM_V_GEN)openssl pkcs12 -inkey $< -in $(builddir)/unit/cert-entity-int.pem -certfile $(builddir)/unit/cert-chain.pem -out $@ -export -passout pass:abc -certpbe PBE-SHA1-RC2-40 -keypbe PBE-SHA1-RC2-128 -macalg sha1
+
+unit/cert-entity-pkcs12-des-sha256.p12: unit/cert-entity-int-key.pem unit/cert-entity-int.pem unit/cert-chain.pem
+ $(AM_V_GEN)openssl pkcs12 -inkey $< -in $(builddir)/unit/cert-entity-int.pem -certfile $(builddir)/unit/cert-chain.pem -out $@ -export -passout pass:abc -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-2DES -macalg sha256
+
+unit/cert-entity-pkcs12-rc4-sha384.p12: unit/cert-entity-int-key.pem unit/cert-entity-int.pem unit/cert-chain.pem
+ $(AM_V_GEN)openssl pkcs12 -inkey $< -in $(builddir)/unit/cert-entity-int.pem -certfile $(builddir)/unit/cert-chain.pem -out $@ -export -passout pass:abc -certpbe PBE-SHA1-RC4-128 -keypbe PBE-SHA1-RC2-40 -macalg sha384
+
+unit/cert-entity-pkcs12-pkcs5-sha512.p12: unit/cert-entity-int-key.pem unit/cert-entity-int.pem unit/cert-chain.pem
+ $(AM_V_GEN)openssl pkcs12 -inkey $< -in $(builddir)/unit/cert-entity-int.pem -certfile $(builddir)/unit/cert-chain.pem -out $@ -export -passout pass:abc -certpbe des-cbc -keypbe des-cbc -macalg sha512
+
+unit/cert-entity-combined.pem: unit/cert-entity-pkcs12-rc2-sha1.p12
+ $(AM_V_GEN)openssl pkcs12 -in $< -out $@ -passin pass:abc -passout pass:abc
+
unit/key-plaintext.h: unit/plaintext.txt
$(AM_V_GEN)xxd -i < $< > $@
--
2.27.0
1 year, 6 months
[PATCH 1/5] acd: store IP in network order
by James Prestwood
The IP target was being converted into host order during
l_acd_start, which required converting back to network order
many times throughout the ACD process. Instead just leave
the IP in network order and use directly. This avoids the
need for conversions and additional temporary variables.
---
ell/acd.c | 24 +++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/ell/acd.c b/ell/acd.c
index ef72fef..7d912d9 100644
--- a/ell/acd.c
+++ b/ell/acd.c
@@ -125,8 +125,6 @@ static int acd_send_packet(struct l_acd *acd, uint32_t source_ip)
{
struct sockaddr_ll dest;
struct ether_arp p;
- uint32_t ip_source;
- uint32_t ip_target;
int n;
int fd = l_io_get_fd(acd->io);
@@ -138,19 +136,17 @@ static int acd_send_packet(struct l_acd *acd, uint32_t source_ip)
dest.sll_halen = ETH_ALEN;
memset(dest.sll_addr, 0xFF, ETH_ALEN);
- ip_source = htonl(source_ip);
- ip_target = htonl(acd->ip);
p.arp_hrd = htons(ARPHRD_ETHER);
p.arp_pro = htons(ETHERTYPE_IP);
p.arp_hln = ETH_ALEN;
p.arp_pln = 4;
p.arp_op = htons(ARPOP_REQUEST);
- ACD_DEBUG("sending packet with target IP %s", IP_STR(ip_target));
+ ACD_DEBUG("sending packet with target IP %s", IP_STR(acd->ip));
memcpy(&p.arp_sha, acd->mac, ETH_ALEN);
- memcpy(&p.arp_spa, &ip_source, sizeof(p.arp_spa));
- memcpy(&p.arp_tpa, &ip_target, sizeof(p.arp_tpa));
+ memcpy(&p.arp_spa, &source_ip, sizeof(p.arp_spa));
+ memcpy(&p.arp_tpa, &acd->ip, sizeof(p.arp_tpa));
n = sendto(fd, &p, sizeof(p), 0,
(struct sockaddr*) &dest, sizeof(dest));
@@ -178,7 +174,7 @@ static void announce_wait_timeout(struct l_timeout *timeout, void *user_data)
if (acd->state == ACD_STATE_PROBE) {
ACD_DEBUG("No conflicts found for %s, announcing address",
- IP_STR(htonl(acd->ip)));
+ IP_STR(acd->ip));
acd->state = ACD_STATE_ANNOUNCED;
@@ -275,7 +271,6 @@ static bool acd_read_handler(struct l_io *io, void *user_data)
int source_conflict;
int target_conflict;
bool probe;
- uint32_t ip;
memset(&arp, 0, sizeof(arp));
len = read(l_io_get_fd(acd->io), &arp, sizeof(arp));
@@ -292,15 +287,14 @@ static bool acd_read_handler(struct l_io *io, void *user_data)
if (memcmp(arp.arp_sha, acd->mac, ETH_ALEN) == 0)
return true;
- ip = htonl(acd->ip);
- source_conflict = !memcmp(arp.arp_spa, &ip, sizeof(uint32_t));
+ source_conflict = !memcmp(arp.arp_spa, &acd->ip, sizeof(uint32_t));
probe = l_memeqzero(arp.arp_spa, sizeof(uint32_t));
target_conflict = probe &&
- !memcmp(arp.arp_tpa, &ip, sizeof(uint32_t));
+ !memcmp(arp.arp_tpa, &acd->ip, sizeof(uint32_t));
if (!source_conflict && !target_conflict) {
ACD_DEBUG("No target or source conflict detected for %s",
- IP_STR(ip));
+ IP_STR(acd->ip));
return true;
}
@@ -309,7 +303,7 @@ static bool acd_read_handler(struct l_io *io, void *user_data)
/* No reason to continue probing */
ACD_DEBUG("%s conflict detected for %s",
target_conflict ? "Target" : "Source",
- IP_STR(ip));
+ IP_STR(acd->ip));
if (acd->event_func)
acd->event_func(L_ACD_EVENT_CONFLICT, acd->user_data);
@@ -454,7 +448,7 @@ LIB_EXPORT bool l_acd_start(struct l_acd *acd, const char *ip)
l_io_set_close_on_destroy(acd->io, true);
l_io_set_read_handler(acd->io, acd_read_handler, acd, NULL);
- acd->ip = ntohl(ia.s_addr);
+ acd->ip = ia.s_addr;
/*
* Optimization to allows skipping the probe stage. The RFC does not
--
2.26.2
1 year, 6 months