From 5224db78081c01091f2c119b68d3905361604bd2 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 1/22] Add a couple of missing header includes Add a couple of missing header inclusions to a couple of the test helpers. Signed-off-by: Nalin Dahyabhai --- diff --git a/tests/tools/pk7decrypt.c b/tests/tools/pk7decrypt.c index 07da465..bac3d3c 100644 --- a/tests/tools/pk7decrypt.c +++ b/tests/tools/pk7decrypt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Red Hat, Inc. + * Copyright (C) 2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,8 @@ #include #include +#include +#include #include "../../src/log.h" #include "../../src/pkcs7.h" diff --git a/tests/tools/pk7verify.c b/tests/tools/pk7verify.c index 906b4ca..97bfef4 100644 --- a/tests/tools/pk7verify.c +++ b/tests/tools/pk7verify.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Red Hat, Inc. + * Copyright (C) 2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,8 @@ #include #include +#include +#include #include "../../src/log.h" #include "../../src/pkcs7.h" From 2da6d13e47a558a317f69b1ebba7221e68f0854b Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 2/22] Make checks for "MAC verified OK" message optional When verifying PKCS#12 bundles, don't expect a "MAC verified OK" message with the MAC is verified, since newer versions of OpenSSL's pkcs12 command don't print the message. They still print an error if verification fails, so strip the verification message from the expected results to accept the output from older versions. Signed-off-by: Nalin Dahyabhai --- diff --git a/tests/003-csrgen-dsa/run.sh b/tests/003-csrgen-dsa/run.sh index c2875ab..2d4a5e1 100755 --- a/tests/003-csrgen-dsa/run.sh +++ b/tests/003-csrgen-dsa/run.sh @@ -12,7 +12,7 @@ run_certutil -d "$tmpdir" -S -g $size -n keyi$size \ -x -t u -k dsa # Export the key. pk12util -d "$tmpdir" -o $size.p12 -W "" -n "keyi$size" > /dev/null 2>&1 -openssl pkcs12 -in $size.p12 -out key.$size -passin pass: -nodes -nocerts > /dev/null 2>&1 +openssl pkcs12 -in $size.p12 -out key.$size -passin pass: -nodes -nocerts > /dev/null 2>&1 | grep -v '^MAC verified OK$' || : # Read the public key and cache it. cat > entry.openssl.$size <<- EOF key_storage_type=FILE diff --git a/tests/003-csrgen-ec/run.sh b/tests/003-csrgen-ec/run.sh index 0620c8f..91117ec 100755 --- a/tests/003-csrgen-ec/run.sh +++ b/tests/003-csrgen-ec/run.sh @@ -13,7 +13,7 @@ run_certutil -d "$tmpdir" -S -n keyi$size \ -x -t u -k ec -q $size # Export the key. pk12util -d "$tmpdir" -o $size.p12 -W "" -n "keyi$size" > /dev/null 2>&1 -openssl pkcs12 -in $size.p12 -out key.$size -passin pass: -nodes -nocerts > /dev/null 2>&1 +openssl pkcs12 -in $size.p12 -out key.$size -passin pass: -nodes -nocerts > /dev/null 2>&1 | ( grep -v '^MAC verified OK$' || : ) # Read the public key and cache it. cat > entry.openssl.$size <<- EOF key_storage_type=FILE diff --git a/tests/003-csrgen-rsa/expected.out b/tests/003-csrgen-rsa/expected.out index e058e85..c9dec72 100644 --- a/tests/003-csrgen-rsa/expected.out +++ b/tests/003-csrgen-rsa/expected.out @@ -1,21 +1,16 @@ pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK 1024 OK. Signature OK pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK 1536 OK. Signature OK pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK 2048 OK. Signature OK pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK 3072 OK. Signature OK pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK 4096 OK. Signature OK The last CSR (the one with everything) was: diff --git a/tests/003-csrgen-rsa/run.sh b/tests/003-csrgen-rsa/run.sh index 7f1e7b4..4cd8408 100755 --- a/tests/003-csrgen-rsa/run.sh +++ b/tests/003-csrgen-rsa/run.sh @@ -12,7 +12,7 @@ for size in 1024 1536 2048 3072 4096 ; do -x -t u -k rsa # Export the key. pk12util -d "$tmpdir" -o $size.p12 -W "" -n "keyi$size" - openssl pkcs12 -in $size.p12 -out key.$size -passin pass: -nodes -nocerts 2>&1 + openssl pkcs12 -in $size.p12 -out key.$size -passin pass: -nodes -nocerts 2>&1 | ( grep -v '^MAC verified OK$' || : ) # Read the public key and cache it. cat > entry.openssl.$size <<- EOF key_storage_type=FILE diff --git a/tests/003-csrgen/expected.out b/tests/003-csrgen/expected.out index 5108316..8e6cac6 100644 --- a/tests/003-csrgen/expected.out +++ b/tests/003-csrgen/expected.out @@ -1,25 +1,20 @@ pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK Signature OK minicert.openssl.1024.pem: OK 1024 OK. pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK Signature OK minicert.openssl.1536.pem: OK 1536 OK. pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK Signature OK minicert.openssl.2048.pem: OK 2048 OK. pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK Signature OK minicert.openssl.3072.pem: OK 3072 OK. pk12util: PKCS12 EXPORT SUCCESSFUL -MAC verified OK Signature OK minicert.openssl.4096.pem: OK 4096 OK. diff --git a/tests/003-csrgen/run.sh b/tests/003-csrgen/run.sh index 67b1206..7c169ed 100755 --- a/tests/003-csrgen/run.sh +++ b/tests/003-csrgen/run.sh @@ -12,7 +12,7 @@ for size in 1024 1536 2048 3072 4096 ; do -x -t u # Export the key. pk12util -d "$tmpdir" -o $size.p12 -W "" -n "keyi$size" - openssl pkcs12 -in $size.p12 -out key.$size -passin pass: -nodes -nocerts 2>&1 + openssl pkcs12 -in $size.p12 -out key.$size -passin pass: -nodes -nocerts 2>&1 | ( grep -v "^MAC verified OK$" || : ) # Read the public key and cache it. cat > entry.openssl.$size <<- EOF key_storage_type=FILE From 27aed86176caeea76d956d02603639ebf3eefdab Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 3/22] Handle the correct version from 'openssl req' When newer versions of 'openssl req' display a request, they add whitespace around the '=' in DNs and correctly interpret a version number field with value 0 as indicating version 1 of the spec. Update the expected output and filter to accept either version. Signed-off-by: Nalin Dahyabhai --- diff --git a/tests/026-local/expected.out b/tests/026-local/expected.out index 776a4c8..1f81c7c 100644 --- a/tests/026-local/expected.out +++ b/tests/026-local/expected.out @@ -3,7 +3,7 @@ OK. [csr] Certificate Request: Data: - Version: 0 (0x0) + Version: 1 (0x0) Subject: CN=Babs Jensen's Signer Attributes: friendlyName :unable to print attribute diff --git a/tests/026-local/run.sh b/tests/026-local/run.sh index b1966a2..6f0e74c 100755 --- a/tests/026-local/run.sh +++ b/tests/026-local/run.sh @@ -17,6 +17,8 @@ template_nscomment=certmonger generated this request template_no_ocsp_check=1 EOF filter() { + sed -re 's,Version: 0 \(0x0\),Version: 1 (0x0),g' |\ + sed -re 's,CN = ,CN=,g' |\ sed -re 's,CN=[[:xdigit:]]{8}-[[:xdigit:]]{8}-[[:xdigit:]]{8}-[[:xdigit:]]{8},CN=$UUID,g' |\ sed -re 's,[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2},(160 bits),g' |\ sed s,'^ Signature Algorithm, Signature Algorithm,g' From 6207548bf4d5fc663fb2e29ba7ca42641519f4c1 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 4/22] Handle X509 version being optional in tests Newer versions of OpenSSL depart from older versions (and NSS) in that they skip the version field when encoding a certificate where the field, which is optional, has the default value of 0, indicating a v1 certificate. To keep minicerts produced by both CSR generation implementations the same, force the version to 3 (encoded value: 2) for the tests. Signed-off-by: Nalin Dahyabhai --- diff --git a/src/csrgen-n.c b/src/csrgen-n.c index aaf9f6e..f8560bc 100644 --- a/src/csrgen-n.c +++ b/src/csrgen-n.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2010,2011,2012,2013,2014,2015 Red Hat, Inc. + * Copyright (C) 2009,2010,2011,2012,2013,2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -791,7 +791,8 @@ cm_csrgen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, nowe.len = strlen(now); validity->notAfter = nowe; minicert = CERT_CreateCertificate(1, name, validity, req); - SEC_ASN1EncodeInteger(arena, &minicert->version, 0); + SEC_ASN1EncodeInteger(arena, &minicert->version, + cm_csrgen_version_for_testing_minicerts); if ((spkidigest[1] & 0x80) != 0) { minicert->serialNumber.data = spkidigest; minicert->serialNumber.len = cm_prefs_nss_dig_alg_len() + 1; diff --git a/src/csrgen-o.c b/src/csrgen-o.c index 63dd555..b8dc609 100644 --- a/src/csrgen-o.c +++ b/src/csrgen-o.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2010,2011,2012,2013,2014,2015 Red Hat, Inc. + * Copyright (C) 2009,2010,2011,2012,2013,2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -343,16 +343,12 @@ cm_csrgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, ASN1_GENERALIZEDTIME_set_string(minicert->cert_info->validity->notAfter, nows); X509_NAME_set(&minicert->cert_info->issuer, subject); X509_NAME_set(&minicert->cert_info->subject, subject); - /* This used to just be X509_set_version(), but - * starting in 1.0.2, OpenSSL began setting it to NULL - * for v1, which breaks tests which expect identical - * output from both NSS and OpenSSL. */ version = M_ASN1_INTEGER_new(); if (version == NULL) { cm_log(1, "Out of memory creating mini certificate.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - ASN1_INTEGER_set(version, 0); + ASN1_INTEGER_set(version, cm_csrgen_version_for_testing_minicerts); minicert->cert_info->version = version; serial = M_ASN1_INTEGER_new(); if (serial == NULL) { diff --git a/src/csrgen.c b/src/csrgen.c index 7b06f03..7c13fe1 100644 --- a/src/csrgen.c +++ b/src/csrgen.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2011,2012,2014 Red Hat, Inc. + * Copyright (C) 2009,2011,2012,2014,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,6 +31,8 @@ #include "log.h" #include "store-int.h" +int cm_csrgen_version_for_testing_minicerts = 0; + int cm_csrgen_read_challenge_password(struct cm_store_entry *entry, char **password) { diff --git a/src/csrgen.h b/src/csrgen.h index bd3fb6d..2044ee7 100644 --- a/src/csrgen.h +++ b/src/csrgen.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2014 Red Hat, Inc. + * Copyright (C) 2009,2014,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,8 @@ struct cm_csrgen_state; struct cm_store_entry; +extern int cm_csrgen_version_for_testing_minicerts; + /* Start CSR generation using template information in the entry. */ struct cm_csrgen_state *cm_csrgen_start(struct cm_store_entry *entry); struct cm_csrgen_state *cm_csrgen_n_start(struct cm_store_entry *entry); diff --git a/tests/tools/csrgen.c b/tests/tools/csrgen.c index 13e1d47..f13c63c 100644 --- a/tests/tools/csrgen.c +++ b/tests/tools/csrgen.c @@ -52,6 +52,11 @@ main(int argc, char **argv) int fd, ret, i; void *parent; char *p; + + /* Make minicerts claim to be v3 so that OpenSSL won't skip the version + * number field, which is optional, because we default to the spec's + * default value. */ + cm_csrgen_version_for_testing_minicerts = 2; cm_log_set_method(cm_log_stderr); cm_log_set_level(3); cm_set_fips_from_env(); From a22d36aed830c7ccdabffc64b539e50744212532 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 5/22] Add an alternate correct 028 output for non-DSA Add a second acceptable set of results for the D-Bus test which expects introspection data from a daemon that doesn't support DSA keys. Signed-off-by: Nalin Dahyabhai --- diff --git a/tests/028-dbus/expected.out.nodsa b/tests/028-dbus/expected.out.nodsa new file mode 100644 index 0000000..a23af40 --- /dev/null +++ b/tests/028-dbus/expected.out.nodsa @@ -0,0 +1,1038 @@ +Certificate in file "${tmpdir}/test.crt" issued by CA and saved. +Certificate in file "${tmpdir}/test.crt" issued by CA and saved. +[[ getcert ]] +State MONITORING, stuck: no. +Number of certificates and requests being tracked: 1. +Request ID 'Buddy': + status: MONITORING + stuck: no + key pair storage: type=FILE,location='$tmpdir/test.key' + certificate: type=FILE,location='$tmpdir/test.crt' + CA: local + issuer: CN=$UUID,CN=Local Signing Authority + subject: CN=localhost + expires: sometime + dns: localhost + principal name: host/localhost@LOCALHOST + key usage: digitalSignature,dataEncipherment + eku: id-kp-serverAuth + certificate template/profile: SomeProfileName + pre-save command: echo Pre + post-save command: echo Post + track: yes + auto-renew: yes +CA 'local': + is-default: no + ca-type: EXTERNAL + helper-location: $tmpdir/local-submit +CA 'SelfSign': + is-default: no + ca-type: INTERNAL:SELF + next-serial-number: 01 +CA 'IPA': + is-default: no + ca-type: EXTERNAL + helper-location: $libexecdir/ipa-submit +CA 'certmaster': + is-default: no + ca-type: EXTERNAL + helper-location: $libexecdir/certmaster-submit +CA 'dogtag-ipa-renew-agent': + is-default: no + ca-type: EXTERNAL + helper-location: $libexecdir/dogtag-ipa-renew-agent-submit + +[[ API ]] +[ simpleprop.py ] +/org/fedorahosted/certmonger/cas/CA6 +/org/fedorahosted/certmonger/cas/CA6 +: -> : -k admin@localhost -> : +0 -> 1 -> 0 +[ walk.py ] +[ /: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + +[ /org: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + +[ /org/fedorahosted: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + +[ /org/fedorahosted/certmonger: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ /org/fedorahosted/certmonger : org.fedorahosted.certmonger.add_known_ca ] +OK + +[ /org/fedorahosted/certmonger : org.fedorahosted.certmonger.add_request ] +OK + +[ /org/fedorahosted/certmonger : org.fedorahosted.certmonger.find_ca_by_nickname ] +OK + +[ /org/fedorahosted/certmonger : org.fedorahosted.certmonger.find_request_by_nickname ] +OK + +[ /org/fedorahosted/certmonger: org.fedorahosted.certmonger.get_known_cas ] +dbus.Array([dbus.ObjectPath('/org/fedorahosted/certmonger/cas/CA1'), dbus.ObjectPath('/org/fedorahosted/certmonger/cas/CA2'), dbus.ObjectPath('/org/fedorahosted/certmonger/cas/CA3'), dbus.ObjectPath('/org/fedorahosted/certmonger/cas/CA4'), dbus.ObjectPath('/org/fedorahosted/certmonger/cas/CA5')], signature=dbus.Signature('o')) + +[ /org/fedorahosted/certmonger: org.fedorahosted.certmonger.get_requests ] +dbus.Array([dbus.ObjectPath('/org/fedorahosted/certmonger/requests/Request2')], signature=dbus.Signature('o')) + +[ /org/fedorahosted/certmonger: org.fedorahosted.certmonger.get_supported_key_types ] +dbus.Array([dbus.String(u'RSA'), dbus.String(u'EC')], signature=dbus.Signature('s')) + +[ /org/fedorahosted/certmonger: org.fedorahosted.certmonger.get_supported_key_storage ] +dbus.Array([dbus.String(u'NSSDB'), dbus.String(u'FILE')], signature=dbus.Signature('s')) + +[ /org/fedorahosted/certmonger: org.fedorahosted.certmonger.get_supported_cert_storage ] +dbus.Array([dbus.String(u'NSSDB'), dbus.String(u'FILE')], signature=dbus.Signature('s')) + +[ /org/fedorahosted/certmonger : org.fedorahosted.certmonger.remove_known_ca ] +OK + +[ /org/fedorahosted/certmonger : org.fedorahosted.certmonger.remove_request ] +OK + +[ /org/fedorahosted/certmonger/requests: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + +[ /org/fedorahosted/certmonger/requests/Request2: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_nickname ] +Buddy + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_autorenew ] +1 + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_cert_data ] + + + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_cert_info ] +(dbus.String(u'CN=$UUID,CN=Local Signing Authority'), dbus.String(u'$UUID'), dbus.String(u'CN=localhost'), dbus.Int64(tomorrow), dbus.Array([], signature=dbus.Signature('s')), dbus.Array([dbus.String(u'localhost')], signature=dbus.Signature('s')), dbus.Array([dbus.String(u'host/localhost@LOCALHOST')], signature=dbus.Signature('s')), dbus.Int64(9L), dbus.Array([dbus.String(u'1.3.6.1.5.5.7.3.1')], signature=dbus.Signature('s'))) + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_cert_last_checked ] +recently + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_cert_storage_info ] +(dbus.String(u'FILE'), dbus.String(u'$tmpdir/test.crt')) + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_csr_data ] + + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_csr_info ] +(dbus.String(u'CN=localhost'), dbus.Array([], signature=dbus.Signature('s')), dbus.Array([dbus.String(u'localhost')], signature=dbus.Signature('s')), dbus.Array([dbus.String(u'host/localhost@LOCALHOST')], signature=dbus.Signature('s')), dbus.Int64(9L), dbus.Array([dbus.String(u'id-kp-serverAuth')], signature=dbus.Signature('s'))) + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_key_pin ] + + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_key_pin_file ] + + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_key_storage_info ] +(dbus.String(u'FILE'), dbus.String(u'$tmpdir/test.key')) + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_key_type_and_size ] +(dbus.String(u'RSA'), dbus.Int64(512L)) + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_monitoring ] +1 + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_notification_info ] +(dbus.String(u'stdout'), dbus.String(u'daemon.notice')) + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_status ] +(dbus.String(u'MONITORING'), dbus.Boolean(False)) + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_ca ] +/org/fedorahosted/certmonger/cas/CA1 + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_submitted_cookie ] +None + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_ca_error ] +None + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.get_submitted_date ] +recently + +[ /org/fedorahosted/certmonger/requests/Request2 : org.fedorahosted.certmonger.request.modify ] +1 on /org/fedorahosted/certmonger/requests/Request2 +After setting template-eku to 1.2.3.4.5.6.7.8.9.10, we got dbus.Array([dbus.String(u'1.2.3.4.5.6.7.8.9.10')], signature=dbus.Signature('s'), variant_level=1) + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.rekey ] +1 + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.resubmit ] +1 + +[ /org/fedorahosted/certmonger/requests/Request2: org.fedorahosted.certmonger.request.refresh ] +0 + +[ /org/fedorahosted/certmonger/cas: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + + + + + +[ /org/fedorahosted/certmonger/cas/CA1: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ /org/fedorahosted/certmonger/cas/CA1: org.fedorahosted.certmonger.ca.get_nickname ] +local + +[ /org/fedorahosted/certmonger/cas/CA1: org.fedorahosted.certmonger.ca.get_is_default ] +0 + +[ /org/fedorahosted/certmonger/cas/CA1: org.fedorahosted.certmonger.ca.get_type ] +EXTERNAL + +[ /org/fedorahosted/certmonger/cas/CA1: org.fedorahosted.certmonger.ca.get_serial ] +None + +[ /org/fedorahosted/certmonger/cas/CA1: org.fedorahosted.certmonger.ca.get_location ] +$tmpdir/local-submit + +[ /org/fedorahosted/certmonger/cas/CA1: org.fedorahosted.certmonger.ca.get_issuer_names ] +dbus.Array([], signature=dbus.Signature('s')) + +[ /org/fedorahosted/certmonger/cas/CA1: org.fedorahosted.certmonger.ca.refresh ] +1 + +[ /org/fedorahosted/certmonger/cas/CA2: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ /org/fedorahosted/certmonger/cas/CA2: org.fedorahosted.certmonger.ca.get_nickname ] +SelfSign + +[ /org/fedorahosted/certmonger/cas/CA2: org.fedorahosted.certmonger.ca.get_is_default ] +0 + +[ /org/fedorahosted/certmonger/cas/CA2: org.fedorahosted.certmonger.ca.get_type ] +INTERNAL:SELF + +[ /org/fedorahosted/certmonger/cas/CA2: org.fedorahosted.certmonger.ca.get_serial ] +01 + +[ /org/fedorahosted/certmonger/cas/CA2: org.fedorahosted.certmonger.ca.get_location ] + + +/org/fedorahosted/certmonger/cas/CA2: warning: property org.fedorahosted.certmonger.ca.external-helper not settable on this object +[ /org/fedorahosted/certmonger/cas/CA2: org.fedorahosted.certmonger.ca.get_issuer_names ] +dbus.Array([], signature=dbus.Signature('s')) + +[ /org/fedorahosted/certmonger/cas/CA2: org.fedorahosted.certmonger.ca.refresh ] +1 + +/org/fedorahosted/certmonger/cas/CA2: warning: property org.fedorahosted.certmonger.ca.scep-ca-identifier not settable on this object +[ /org/fedorahosted/certmonger/cas/CA3: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ /org/fedorahosted/certmonger/cas/CA3: org.fedorahosted.certmonger.ca.get_nickname ] +IPA + +[ /org/fedorahosted/certmonger/cas/CA3: org.fedorahosted.certmonger.ca.get_is_default ] +0 + +[ /org/fedorahosted/certmonger/cas/CA3: org.fedorahosted.certmonger.ca.get_type ] +EXTERNAL + +[ /org/fedorahosted/certmonger/cas/CA3: org.fedorahosted.certmonger.ca.get_serial ] +None + +[ /org/fedorahosted/certmonger/cas/CA3: org.fedorahosted.certmonger.ca.get_location ] +$libexecdir/ipa-submit + +[ /org/fedorahosted/certmonger/cas/CA3: org.fedorahosted.certmonger.ca.get_issuer_names ] +dbus.Array([], signature=dbus.Signature('s')) + +[ /org/fedorahosted/certmonger/cas/CA3: org.fedorahosted.certmonger.ca.refresh ] +1 + +[ /org/fedorahosted/certmonger/cas/CA4: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ /org/fedorahosted/certmonger/cas/CA4: org.fedorahosted.certmonger.ca.get_nickname ] +certmaster + +[ /org/fedorahosted/certmonger/cas/CA4: org.fedorahosted.certmonger.ca.get_is_default ] +0 + +[ /org/fedorahosted/certmonger/cas/CA4: org.fedorahosted.certmonger.ca.get_type ] +EXTERNAL + +[ /org/fedorahosted/certmonger/cas/CA4: org.fedorahosted.certmonger.ca.get_serial ] +None + +[ /org/fedorahosted/certmonger/cas/CA4: org.fedorahosted.certmonger.ca.get_location ] +$libexecdir/certmaster-submit + +[ /org/fedorahosted/certmonger/cas/CA4: org.fedorahosted.certmonger.ca.get_issuer_names ] +dbus.Array([], signature=dbus.Signature('s')) + +[ /org/fedorahosted/certmonger/cas/CA4: org.fedorahosted.certmonger.ca.refresh ] +1 + +[ /org/fedorahosted/certmonger/cas/CA5: org.freedesktop.DBus.Introspectable.Introspect ] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[ /org/fedorahosted/certmonger/cas/CA5: org.fedorahosted.certmonger.ca.get_nickname ] +dogtag-ipa-renew-agent + +[ /org/fedorahosted/certmonger/cas/CA5: org.fedorahosted.certmonger.ca.get_is_default ] +0 + +[ /org/fedorahosted/certmonger/cas/CA5: org.fedorahosted.certmonger.ca.get_type ] +EXTERNAL + +[ /org/fedorahosted/certmonger/cas/CA5: org.fedorahosted.certmonger.ca.get_serial ] +None + +[ /org/fedorahosted/certmonger/cas/CA5: org.fedorahosted.certmonger.ca.get_location ] +$libexecdir/dogtag-ipa-renew-agent-submit + +[ /org/fedorahosted/certmonger/cas/CA5: org.fedorahosted.certmonger.ca.get_issuer_names ] +dbus.Array([], signature=dbus.Signature('s')) + +[ /org/fedorahosted/certmonger/cas/CA5: org.fedorahosted.certmonger.ca.refresh ] +1 + From 863b9782b6a61dceaa97cb5cc4e2649ec2d91ecc Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 6/22] Remove unused cm_submit_n_nid_from_tag() We're not using cm_submit_n_nid_from_tag(), and it won't build against OpenSSL 1.1 without changes, so just drop it. Signed-off-by: Nalin Dahyabhai --- diff --git a/src/submit-n.c b/src/submit-n.c index d7828ca..d8fb517 100644 --- a/src/submit-n.c +++ b/src/submit-n.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Red Hat, Inc. + * Copyright (C) 2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -80,18 +80,6 @@ cm_submit_n_tag_from_nid(int nid) } } -int -cm_submit_n_nid_from_tag(SECOidTag tag) -{ - SECOidData *oid = SECOID_FindOIDByTag(tag); - ASN1_OBJECT obj; - - memset(&obj, 0, sizeof(obj)); - obj.data = oid->oid.data; - obj.length = oid->oid.len; - return OBJ_obj2nid(&obj); -} - static SECItem * try_to_decode(void *parent, PLArenaPool *arena, SECItem *item, SECKEYPrivateKey *privkey) diff --git a/src/submit-o.h b/src/submit-o.h index 23071d9..f064564 100644 --- a/src/submit-o.h +++ b/src/submit-o.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Red Hat, Inc. + * Copyright (C) 2014,2015 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,6 @@ #define cmsubmito_h SECOidTag cm_submit_n_tag_from_nid(int nid); -int cm_submit_n_nid_from_tag(SECOidTag tag); int cm_submit_o_sign(void *parent, char *csr, X509 *signer, EVP_PKEY *signer_key, From 1e70f045c85e02299750ddd2ac014a92e4000c35 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 7/22] Remove a macro we weren't using Remove the WINDOW macro, which we don't use. Signed-off-by: Nalin Dahyabhai --- diff --git a/src/submit-n.c b/src/submit-n.c index d8fb517..7151bab 100644 --- a/src/submit-n.c +++ b/src/submit-n.c @@ -61,7 +61,6 @@ #include "util-o.h" #define PRIVKEY_LIST_EMPTY(l) PRIVKEY_LIST_END(PRIVKEY_LIST_HEAD(l), l) -#define WINDOW (24 * 60 * 60 * PR_USEC_PER_SEC) SECOidTag cm_submit_n_tag_from_nid(int nid) From 92617ab24a96fcb4e83afb49fa266b813c44df2c Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 8/22] Factor out cert_cmp Factor out two cert_cmp() static implementations into a shared function, and teach it to have the right prototype for newer OpenSSL. Signed-off-by: Nalin Dahyabhai --- diff --git a/src/local.c b/src/local.c index e9b9678..ff355da 100644 --- a/src/local.c +++ b/src/local.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014,2015 Red Hat, Inc. + * Copyright (C) 2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -246,7 +246,7 @@ get_signer_info(void *parent, char *localdir, X509 ***roots, * left. */ if (*signer_cert != NULL) { if (cas == NULL) { - cas = sk_X509_new(X509_cmp); + cas = sk_X509_new(util_o_cert_cmp); if (cas == NULL) { cm_log(1, "Out of memory.\n"); return CM_SUBMIT_STATUS_UNREACHABLE; diff --git a/src/pkcs7.c b/src/pkcs7.c index da6ce72..bc6d0ac 100644 --- a/src/pkcs7.c +++ b/src/pkcs7.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Red Hat, Inc. + * Copyright (C) 2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +44,7 @@ #include "scep-o.h" #include "store.h" #include "submit-u.h" +#include "util-o.h" #ifdef ENABLE_NLS #include @@ -121,16 +122,6 @@ pemx509(void *parent, X509 *x) return ret; } -/* Wrap the comparison function to handle the callback indirection. */ -static int -cert_cmp(const void *a, const void *b) -{ - X509 * const *x, * const *y; - x = a; - y = b; - return X509_cmp(*x, *y); -} - /* Return 0 if "candidate" is more like what we're looking for than "current". */ static int betterleaf(X509 *candidate, X509 *current, unsigned int flags) @@ -330,7 +321,7 @@ cm_pkcs7_parsev(unsigned int flags, void *parent, *certtop = NULL; } - sk = sk_X509_new(cert_cmp); + sk = sk_X509_new(util_o_cert_cmp); if (sk == NULL) { return -1; } @@ -559,7 +550,7 @@ cm_pkcs7_envelope_data(char *encryption_cert, enum cm_prefs_cipher cipher, } BIO_free(in); - recipients = sk_X509_new(cert_cmp); + recipients = sk_X509_new(util_o_cert_cmp); if (recipients == NULL) { cm_log(1, "Out of memory.\n"); goto done; @@ -994,7 +985,7 @@ cm_pkcs7_verify_signed(unsigned char *data, size_t length, goto done; } X509_STORE_set_verify_cb_func(store, &ignore_purpose_errors); - certs = sk_X509_new(cert_cmp); + certs = sk_X509_new(util_o_cert_cmp); if (certs == NULL) { cm_log(1, "Out of memory.\n"); goto done; diff --git a/src/scepgen-o.c b/src/scepgen-o.c index d11e3de..3a81b19 100644 --- a/src/scepgen-o.c +++ b/src/scepgen-o.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Red Hat, Inc. + * Copyright (C) 2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -141,17 +141,6 @@ cert_from_pem(char *pem, struct cm_store_entry *entry) return NULL; } -static int -cert_cmp(const void *a, const void *b) -{ - X509 * const *x, * const *y; - - x = a; - y = b; - return X509_cmp(*x, *y); -} - - static STACK_OF(X509) * certs_from_nickcerts(struct cm_nickcert **list) { @@ -176,7 +165,7 @@ certs_from_nickcerts(struct cm_nickcert **list) _exit(CM_SUB_STATUS_INTERNAL_ERROR); } if (sk == NULL) { - sk = sk_X509_new(cert_cmp); + sk = sk_X509_new(util_o_cert_cmp); if (sk == NULL) { cm_log(1, "Out of memory.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); diff --git a/src/util-o.c b/src/util-o.c index fdc3d9c..7109a67 100644 --- a/src/util-o.c +++ b/src/util-o.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010,2015 Red Hat, Inc. + * Copyright (C) 2010,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -149,3 +149,21 @@ util_set_fd_entry_cert_owner(int certfd, const char *filename, util_set_fd_owner_perms(certfd, filename, entry->cm_cert_owner, entry->cm_cert_perms); } + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +int +util_o_cert_cmp(const X509 *const *a, const X509 *const *b) +{ + return X509_cmp(*a, *b); +} +#else +int +util_o_cert_cmp(const void *a, const void *b) +{ + X509 * const *x, * const *y; + + x = a; + y = b; + return X509_cmp(*x, *y); +} +#endif diff --git a/src/util-o.h b/src/util-o.h index aaef8ff..c2ea3ef 100644 --- a/src/util-o.h +++ b/src/util-o.h @@ -29,5 +29,10 @@ void util_set_fd_entry_key_owner(int keyfd, const char *filename, struct cm_store_entry *entry); void util_set_fd_entry_cert_owner(int certfd, const char *filename, struct cm_store_entry *entry); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +int util_o_cert_cmp(const X509 *const *a, const X509 *const *b); +#else +int util_o_cert_cmp(const void *a, const void *b); +#endif #endif From 83943d8a0c5e04fb8d60c3f91bb1986979e56c9b Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 9/22] Go back to timestamp-based identifiers for now Go back from using UUIDs for request IDs and file names to using ad-hoc timestamp-based values, since we still don't place hard requirements on the libraries that we'd use for generating those UUIDs, which means we could compile and fail to save any data to files. Signed-off-by: Nalin Dahyabhai --- diff --git a/src/cm.c b/src/cm.c index 7022d96..f3a9bd5 100644 --- a/src/cm.c +++ b/src/cm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2010,2011,2014,2015 Red Hat, Inc. + * Copyright (C) 2009,2010,2011,2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -600,7 +600,8 @@ cm_add_entry(struct cm_context *context, struct cm_store_entry *new_entry) struct cm_store_entry **entries; struct cm_event *events; int i; - char uuidstring[37]; + time_t now; + char timestamp[15]; /* Check for duplicates and count the number of entries we're already * managing. */ @@ -612,11 +613,23 @@ cm_add_entry(struct cm_context *context, struct cm_store_entry *new_entry) } } } else { - /* Assign a new ID. */ - if (cm_store_make_uuid_string_underscore(uuidstring) < 0) { - return -1; - } - new_entry->cm_nickname = talloc_strdup(new_entry, uuidstring); + do { + /* Try to assign a new ID. */ + now = cm_time(NULL); + new_entry->cm_nickname = cm_store_timestamp_from_time(now, + timestamp); + /* Check for duplicates. */ + for (i = 0; i < context->n_entries; i++) { + if (strcmp(context->entries[i]->cm_nickname, + new_entry->cm_nickname) == 0) { + /* Busy wait 0.1s. Ugh. */ + usleep(100000); + break; + } + } + } while (i < context->n_entries); + new_entry->cm_nickname = talloc_strdup(new_entry, + new_entry->cm_nickname); } /* Resize the entry array. */ events = NULL; @@ -991,7 +1004,8 @@ cm_add_ca(struct cm_context *context, struct cm_store_ca *new_ca) struct cm_store_ca **cas; struct cm_ca_event *events; int i; - char uuidstring[37]; + time_t now; + char timestamp[15]; enum cm_ca_phase phase; /* Check for duplicates and count the number of CAs we're already @@ -1004,11 +1018,23 @@ cm_add_ca(struct cm_context *context, struct cm_store_ca *new_ca) } } } else { - /* Assign a new ID. */ - if (cm_store_make_uuid_string_underscore(uuidstring) < 0) { - return -1; - } - new_ca->cm_nickname = talloc_strdup(new_ca, uuidstring); + do { + /* Try to assign a new nickname. */ + now = cm_time(NULL); + new_ca->cm_nickname = cm_store_timestamp_from_time(now, + timestamp); + /* Check for duplicates. */ + for (i = 0; i < context->n_cas; i++) { + if (strcmp(context->cas[i]->cm_nickname, + new_ca->cm_nickname) == 0) { + /* Busy wait 0.1s. Ugh. */ + usleep(100000); + break; + } + } + } while (i < context->n_cas); + new_ca->cm_nickname = talloc_strdup(new_ca, + new_ca->cm_nickname); } /* Allocate storage for a new CA array. */ cas = talloc_realloc(context, context->cas, struct cm_store_ca *, diff --git a/src/store-files.c b/src/store-files.c index 08ee0c6..dbeebce 100644 --- a/src/store-files.c +++ b/src/store-files.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2010,2011,2012,2013,2014,2015 Red Hat, Inc. + * Copyright (C) 2009,2010,2011,2012,2013,2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1769,15 +1769,11 @@ cm_store_file_write_nickcert_list(FILE *fp, enum cm_store_file_field field, static int cm_store_entry_write(FILE *fp, struct cm_store_entry *entry) { - char timestamp[15], uuidstring[37]; + char timestamp[15]; const char *p; if (entry->cm_nickname == NULL) { - if (cm_store_make_uuid_string_underscore(uuidstring) > 0) { - p = uuidstring; - } else { - return -1; - } + p = cm_store_timestamp_from_time(cm_time(NULL), timestamp); } else { p = entry->cm_nickname; } @@ -2198,16 +2194,16 @@ int cm_store_entry_save(struct cm_store_entry *entry) { FILE *fp; - char timestamp[15], path[PATH_MAX], uuidstring[37]; + char timestamp[15], path[PATH_MAX]; int i, fd = -1, give_up; const char *directory, *dest; if (entry->cm_store_private == NULL) { - cm_store_make_uuid_string(uuidstring); + cm_store_timestamp_from_time(cm_time(NULL), timestamp); directory = cm_env_request_dir(); if (directory != NULL) { snprintf(path, sizeof(path), "%s/%s", - directory, uuidstring); + directory, timestamp); fd = open(path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); @@ -2344,14 +2340,10 @@ static int cm_store_ca_write(FILE *fp, struct cm_store_ca *ca) { const char *p; - char uuidstring[37]; + char timestamp[15]; if (ca->cm_nickname == NULL) { - if (cm_store_make_uuid_string_underscore(uuidstring) > 0) { - p = uuidstring; - } else { - return -1; - } + p = cm_store_timestamp_from_time(cm_time(NULL), timestamp); } else { p = ca->cm_nickname; } @@ -2460,15 +2452,15 @@ int cm_store_ca_save(struct cm_store_ca *ca) { FILE *fp; - char timestamp[15], path[PATH_MAX], uuidstring[37]; + char timestamp[15], path[PATH_MAX]; int i, fd = -1, give_up; const char *directory, *dest; if (ca->cm_store_private == NULL) { - cm_store_make_uuid_string(uuidstring); + cm_store_timestamp_from_time(cm_time(NULL), timestamp); directory = cm_env_ca_dir(); if (directory != NULL) { - snprintf(path, sizeof(path), "%s/%s", directory, uuidstring); + snprintf(path, sizeof(path), "%s/%s", directory, timestamp); fd = open(path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); From d2a8bc3220d6e9f89662cdd2eaadc0fd97d74c9a Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 10/22] Build with -DOPENSSL_NO_DEPRECATED Disable deprecated OpenSSL functionality at build-time, so that we can hopefully be more proactive about keeping up with API changes. Signed-off-by: Nalin Dahyabhai --- diff --git a/configure.ac b/configure.ac index de33bf8..a56fff3 100644 --- a/configure.ac +++ b/configure.ac @@ -333,7 +333,7 @@ if ! ${configure_dist_target_only:-false} ; then AC_DEFINE(HAVE_OPENSSL,1,[Define if you have OpenSSL.]) CFLAGSsave="$CFLAGS" LIBSsave="$LIBS" - CFLAGS="$OPENSSL_CFLAGS $CFLAGS" + CFLAGS="$OPENSSL_CFLAGS $CFLAGS -DOPENSSL_NO_DEPRECATED" LIBS="$OPENSSL_LIBS $LIBS" AC_CHECK_DECLS([OpenSSL_add_all_algorithms,OpenSSL_add_ssl_algorithms],,,[#include ]) AC_CHECK_DECLS(OPENSSL_free,,,[#include ]) From a1c822ebd5cf33aba9b2cab3c5d548b9768580b7 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 11/22] Add missing includes of Make sure we include , if it exists, everywhere we include . Signed-off-by: Nalin Dahyabhai --- diff --git a/src/ipa.c b/src/ipa.c index b8c5b79..bc0c851 100644 --- a/src/ipa.c +++ b/src/ipa.c @@ -21,7 +21,11 @@ #include #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include +#include #include #include #include diff --git a/src/json.c b/src/json.c index c454ff9..e2bce94 100644 --- a/src/json.c +++ b/src/json.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Red Hat, Inc. + * Copyright (C) 2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,9 @@ #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include #include #include diff --git a/src/local.c b/src/local.c index ff355da..d0408f0 100644 --- a/src/local.c +++ b/src/local.c @@ -21,7 +21,11 @@ #include #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include +#include #include #include #include diff --git a/src/pkcs7.c b/src/pkcs7.c index bc6d0ac..157f5aa 100644 --- a/src/pkcs7.c +++ b/src/pkcs7.c @@ -18,7 +18,11 @@ #include "config.h" #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include +#include #include #include diff --git a/src/prefs-o.c b/src/prefs-o.c index c2e35ea..9835190 100644 --- a/src/prefs-o.c +++ b/src/prefs-o.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +17,12 @@ #include "config.h" +#include +#ifdef HAVE_INTTYPES_H +#include +#endif +#include + #include #include diff --git a/src/scep.c b/src/scep.c index a9f945f..1ddb883 100644 --- a/src/scep.c +++ b/src/scep.c @@ -21,7 +21,11 @@ #include #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include +#include #include #include #include diff --git a/src/srvloc.c b/src/srvloc.c index 0f8c383..c80bebb 100644 --- a/src/srvloc.c +++ b/src/srvloc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Red Hat, Inc. + * Copyright (C) 2014,2016,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,9 @@ #include #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include #include #include diff --git a/src/submit-e.c b/src/submit-e.c index d21635b..8ba8e44 100644 --- a/src/submit-e.c +++ b/src/submit-e.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2011,2012,2013,2014,2015 Red Hat, Inc. + * Copyright (C) 2009,2011,2012,2013,2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,9 @@ #include #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include #include #include diff --git a/src/tdbusm.c b/src/tdbusm.c index 9c603ea..bc39e1d 100644 --- a/src/tdbusm.c +++ b/src/tdbusm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2010,2011,2012 Red Hat, Inc. + * Copyright (C) 2009,2010,2011,2012,2014,2015 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,9 @@ #include "config.h" #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include #include #include diff --git a/src/util-o.c b/src/util-o.c index 7109a67..e187890 100644 --- a/src/util-o.c +++ b/src/util-o.c @@ -22,7 +22,11 @@ #include #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include +#include #include #include diff --git a/tests/tools/json-utf8.c b/tests/tools/json-utf8.c index 216fc23..20bb405 100644 --- a/tests/tools/json-utf8.c +++ b/tests/tools/json-utf8.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Red Hat, Inc. + * Copyright (C) 2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,9 @@ #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include #include #include diff --git a/tests/tools/json.c b/tests/tools/json.c index e42b1da..6171640 100644 --- a/tests/tools/json.c +++ b/tests/tools/json.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Red Hat, Inc. + * Copyright (C) 2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +21,9 @@ #include #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include #include #include diff --git a/tests/tools/pk7decrypt.c b/tests/tools/pk7decrypt.c index bac3d3c..017e73f 100644 --- a/tests/tools/pk7decrypt.c +++ b/tests/tools/pk7decrypt.c @@ -21,7 +21,11 @@ #include #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include +#include #include #include #include diff --git a/tests/tools/pk7verify.c b/tests/tools/pk7verify.c index 97bfef4..7615fa5 100644 --- a/tests/tools/pk7verify.c +++ b/tests/tools/pk7verify.c @@ -21,7 +21,11 @@ #include #include #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include +#include #include #include #include diff --git a/tests/tools/srv.c b/tests/tools/srv.c index e64be62..884701c 100644 --- a/tests/tools/srv.c +++ b/tests/tools/srv.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014,2015 Red Hat, Inc. + * Copyright (C) 2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,9 @@ #include "../../src/config.h" #include +#ifdef HAVE_INTTYPES_H +#include +#endif #include #include #include From 5edd847a328676cc551ea00f248ca8fbf293bedd Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 12/22] Simplify pkcs7 issuerissued() Simplify the implementation of issuerissued(). The key identifier checks that it performs were there because I thought they weren't done by X509_check_issued(), but I was mistaken. Signed-off-by: Nalin Dahyabhai --- diff --git a/src/pkcs7.c b/src/pkcs7.c index 157f5aa..c5cf2c3 100644 --- a/src/pkcs7.c +++ b/src/pkcs7.c @@ -62,35 +62,11 @@ static int issuerissued(X509 *issuer, X509 *issued) { - GENERAL_NAME *gn; - int i; - - if ((issuer->skid != NULL) && - (issued->akid != NULL) && - (issued->akid->keyid != NULL)) { - if (M_ASN1_OCTET_STRING_cmp(issuer->skid, - issued->akid->keyid) == 0) { - return 0; - } - } - if ((issued->akid != NULL) && - (issued->akid->issuer != NULL) && - (issued->akid->serial != NULL)) { - for (i = 0; - i < sk_GENERAL_NAME_num(issued->akid->issuer); - i++) { - gn = sk_GENERAL_NAME_value(issued->akid->issuer, i); - if ((gn->type == GEN_DIRNAME) && - (X509_NAME_cmp(issuer->cert_info->issuer, - gn->d.dirn) == 0) && - (M_ASN1_INTEGER_cmp(issuer->cert_info->serialNumber, - issued->akid->serial) == 0)) { - return 0; - } - } + if (X509_check_issued(issuer, issued) == X509_V_OK) { + return 0; } - return X509_name_cmp(issuer->cert_info->subject, - issued->cert_info->issuer); + return X509_name_cmp(util_X509_get0_subject_name(issuer), + util_X509_get0_issuer_name(issued)); } /* Render the certificate as a PEM string. */ From d56a546bde0eda6f6ea549a0c586eb6b2bca3a3c Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 13/22] Finish porting to OpenSSL 1.1 Check for new accessor functions, and wrap them in functions that attempt to access the structure members directly when the accessor functions aren't available. In a couple of places, encode a structure to DER, decode it with NSS, modify the NSS version of the structure, re-encode it to DER, and re-decode it. Learn to duplicate EVP_PKEYs by encoding to DER and decoding. Signed-off-by: Nalin Dahyabhai --- diff --git a/configure.ac b/configure.ac index a56fff3..80234e3 100644 --- a/configure.ac +++ b/configure.ac @@ -337,6 +337,58 @@ if ! ${configure_dist_target_only:-false} ; then LIBS="$OPENSSL_LIBS $LIBS" AC_CHECK_DECLS([OpenSSL_add_all_algorithms,OpenSSL_add_ssl_algorithms],,,[#include ]) AC_CHECK_DECLS(OPENSSL_free,,,[#include ]) + AC_CHECK_FUNCS(ASN1_BIT_STRING_new) + AC_CHECK_FUNCS(ASN1_GENERALIZEDTIME_new) + AC_CHECK_FUNCS(ASN1_IA5STRING_new) + AC_CHECK_FUNCS(ASN1_INTEGER_new) + AC_CHECK_FUNCS(ASN1_OCTET_STRING_new) + AC_CHECK_FUNCS(ASN1_OCTET_STRING_set) + AC_CHECK_FUNCS(ASN1_PRINTABLESTRING_new) + AC_CHECK_FUNCS(ASN1_STRING_get0_data) + AC_CHECK_FUNCS(ASN1_STRING_get_data) + AC_CHECK_FUNCS(ASN1_STRING_length) + AC_CHECK_FUNCS(ASN1_STRING_new) + AC_CHECK_FUNCS(ASN1_TIME_dup) + AC_CHECK_FUNCS(ASN1_TIME_new) + AC_CHECK_FUNCS(ASN1_TIME_set) + AC_CHECK_FUNCS(EVP_PKEY_base_id) + AC_CHECK_FUNCS(EVP_PKEY_id) + AC_CHECK_FUNCS(OBJ_get0_data) + AC_CHECK_FUNCS(OBJ_length) + AC_CHECK_FUNCS(X509_ATTRIBUTE_get0_object) + AC_CHECK_FUNCS(X509_get0_notAfter) + AC_CHECK_FUNCS(X509_get0_pubkey) + AC_CHECK_FUNCS(X509_get0_serialNumber) + AC_CHECK_FUNCS(X509_get_issuer_name) + AC_CHECK_FUNCS(X509_get_key_usage) + AC_CHECK_FUNCS(X509_get_subject_name) + AC_CHECK_FUNCS(X509_REQ_get0_pubkey) + AC_CHECK_FUNCS(X509_REQ_get0_signature) + AC_CHECK_FUNCS(X509_REQ_set_subject_name) + AC_CHECK_FUNCS(X509_set1_notAfter) + AC_CHECK_FUNCS(X509_set1_notBefore) + AC_CHECK_FUNCS(X509_set_issuer_name) + AC_CHECK_FUNCS(X509_set_pubkey) + AC_CHECK_FUNCS(X509_set_subject_name) + AC_CHECK_FUNCS(X509_set_version) + AC_CHECK_MEMBERS(X509.cert_info,,, + [ + #include + ]) + AC_MSG_CHECKING([if NETSCAPE_SPKI.sig_algor is a pointer or a struct]) + have_sig_algor_pointer=unknown + AC_LINK_IFELSE(AC_LANG_PROGRAM([ + #include + #include + ],[ + NETSCAPE_SPKI spki; + spki.sig_algor = NULL; + ]), + AC_DEFINE(CM_NETSCAPE_SPKI_SIG_ALGOR_IS_POINTER,1,[Define if NETSCAPE_SPKI.sig_algor is a pointer]) + have_sig_algor_pointer="pointer to X509_ALGOR", + have_sig_algor_pointer=X509_ALGOR + ) + AC_MSG_RESULT($have_sig_algor_pointer) CFLAGS="$CFLAGSsave" LIBS="$LIBSsave" fi diff --git a/src/certsave-o.c b/src/certsave-o.c index 917389a..77f54d7 100644 --- a/src/certsave-o.c +++ b/src/certsave-o.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2010,2011,2013,2014,2015 Red Hat, Inc. + * Copyright (C) 2009,2010,2011,2013,2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -252,7 +252,7 @@ cm_certsave_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, if (bio != NULL) { cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); if (cert != NULL) { - bn = ASN1_INTEGER_to_BN(cert->cert_info->serialNumber, NULL); + bn = ASN1_INTEGER_to_BN(util_X509_get0_serialNumber(cert), NULL); if (bn != NULL) { bin = malloc(BN_num_bytes(bn)); if (bin != NULL) { diff --git a/src/csrgen-o.c b/src/csrgen-o.c index b8dc609..55b0a59 100644 --- a/src/csrgen-o.c +++ b/src/csrgen-o.c @@ -84,8 +84,10 @@ cm_csrgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, FILE *keyfp, *status; X509_REQ *req; X509_NAME *subject; + const X509_ALGOR *sig_alg; X509 *minicert; ASN1_INTEGER *serial, *version; + ASN1_GENERALIZEDTIME *notBefore = NULL, *notAfter = NULL; NETSCAPE_SPKI spki; NETSCAPE_SPKAC spkac; EVP_PKEY *pkey; @@ -229,7 +231,7 @@ cm_csrgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, } } if (subject != NULL) { - X509_NAME_set(&req->req_info->subject, subject); + util_X509_REQ_set_subject_name(req, subject); } X509_REQ_set_pubkey(req, pkey); X509_REQ_set_version(req, SEC_CERTIFICATE_REQUEST_VERSION); @@ -288,7 +290,7 @@ cm_csrgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, PEM_write_X509_REQ_NEW(status, req); /* Generate the SPKAC. */ memset(&spkac, 0, sizeof(spkac)); - spkac.challenge = M_ASN1_IA5STRING_new(); + spkac.challenge = util_ASN1_IA5STRING_new(); if (password != NULL) { ASN1_STRING_set(spkac.challenge, password, strlen(password)); @@ -298,8 +300,9 @@ cm_csrgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, } memset(&spki, 0, sizeof(spki)); spki.spkac = &spkac; - spki.sig_algor = req->sig_alg; - spki.signature = M_ASN1_BIT_STRING_new(); + util_X509_REQ_get0_signature(req, NULL, &sig_alg); + util_NETSCAPE_SPKI_set_sig_alg(&spki, sig_alg); + spki.signature = util_ASN1_BIT_STRING_new(); NETSCAPE_SPKI_set_pubkey(&spki, pkey); NETSCAPE_SPKI_sign(&spki, pkey, cm_prefs_ossl_hash()); s = NETSCAPE_SPKI_b64_encode(&spki); @@ -335,22 +338,24 @@ cm_csrgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, now = gmtime(&nowt); nows = talloc_asprintf(entry, "%04d%02d%02d000000Z", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday); - minicert->cert_info->validity->notBefore = M_ASN1_GENERALIZEDTIME_new(); - ASN1_GENERALIZEDTIME_set_string(minicert->cert_info->validity->notBefore, nows); + notBefore = util_ASN1_GENERALIZEDTIME_new(); + ASN1_GENERALIZEDTIME_set_string(notBefore, nows); + util_X509_set1_notBefore(minicert, notBefore); nows = talloc_asprintf(entry, "%04d%02d%02d000000Z", now->tm_year + 1900 + 100, now->tm_mon + 1, now->tm_mday); - minicert->cert_info->validity->notAfter = M_ASN1_GENERALIZEDTIME_new(); - ASN1_GENERALIZEDTIME_set_string(minicert->cert_info->validity->notAfter, nows); - X509_NAME_set(&minicert->cert_info->issuer, subject); - X509_NAME_set(&minicert->cert_info->subject, subject); - version = M_ASN1_INTEGER_new(); + notAfter = util_ASN1_GENERALIZEDTIME_new(); + ASN1_GENERALIZEDTIME_set_string(notAfter, nows); + util_X509_set1_notAfter(minicert, notAfter); + util_X509_set_issuer_name(minicert, subject); + util_X509_set_subject_name(minicert, subject); + version = util_ASN1_INTEGER_new(); if (version == NULL) { cm_log(1, "Out of memory creating mini certificate.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } ASN1_INTEGER_set(version, cm_csrgen_version_for_testing_minicerts); - minicert->cert_info->version = version; - serial = M_ASN1_INTEGER_new(); + util_X509_set1_version(minicert, version); + serial = util_ASN1_INTEGER_new(); if (serial == NULL) { cm_log(1, "Out of memory creating mini certificate.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); diff --git a/src/keyiread-o.c b/src/keyiread-o.c index faee3f0..9fceacf 100644 --- a/src/keyiread-o.c +++ b/src/keyiread-o.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2010,2011,2012,2014,2015 Red Hat, Inc. + * Copyright (C) 2009,2010,2011,2012,2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -152,7 +152,7 @@ cm_keyiread_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, pubkey = ""; pubikey = ""; if (pkey != NULL) { - switch (EVP_PKEY_type(pkey->type)) { + switch (util_EVP_PKEY_base_id(pkey)) { case EVP_PKEY_RSA: cm_log(3, "Key is an RSA key.\n"); alg = "RSA"; @@ -189,7 +189,7 @@ cm_keyiread_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, } fprintf(fp, "%s/%d/%s/%s\n", alg, bits, pubikey, pubkey); if (nextpkey != NULL) { - switch (EVP_PKEY_type(nextpkey->type)) { + switch (util_EVP_PKEY_base_id(nextpkey)) { case EVP_PKEY_RSA: cm_log(3, "Next key is an RSA key.\n"); alg = "RSA"; diff --git a/src/local.c b/src/local.c index d0408f0..c71bb04 100644 --- a/src/local.c +++ b/src/local.c @@ -93,15 +93,15 @@ set_ca_extensions(void *parent, X509_REQ *req, EVP_PKEY *key) q = p; len = i2d_PUBKEY(key, &q); if (EVP_Digest(p, len, md, &mdlen, EVP_sha1(), NULL)) { - skid = M_ASN1_OCTET_STRING_new(); - M_ASN1_OCTET_STRING_set(skid, md, mdlen); + skid = util_ASN1_OCTET_STRING_new(); + util_ASN1_OCTET_STRING_set(skid, md, mdlen); memset(&akid, 0, sizeof(akid)); akid.keyid = skid; X509V3_add1_i2d(&exts, NID_subject_key_identifier, skid, 0, 0); X509V3_add1_i2d(&exts, NID_authority_key_identifier, &akid, 0, 0); } - ku = M_ASN1_BIT_STRING_new(); + ku = util_ASN1_BIT_STRING_new(); ASN1_BIT_STRING_set_bit(ku, 0, 1); ASN1_BIT_STRING_set_bit(ku, 5, 1); ASN1_BIT_STRING_set_bit(ku, 6, 1); @@ -124,9 +124,9 @@ make_ca_csr(void *parent, EVP_PKEY *key, X509 *oldcert) req = X509_REQ_new(); if (req != NULL) { if ((oldcert != NULL) && - (oldcert->cert_info->subject != NULL)) { + (X509_get_subject_name(oldcert) != NULL)) { X509_REQ_set_subject_name(req, - oldcert->cert_info->subject); + X509_get_subject_name(oldcert)); } else { subject = X509_NAME_new(); if (subject != NULL) { diff --git a/src/pkcs7.c b/src/pkcs7.c index c5cf2c3..79af491 100644 --- a/src/pkcs7.c +++ b/src/pkcs7.c @@ -107,8 +107,8 @@ static int betterleaf(X509 *candidate, X509 *current, unsigned int flags) { if (flags & CM_PKCS7_LEAF_PREFER_ENCRYPT) { - if (((candidate->ex_kusage & (KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT)) != 0) && - ((current->ex_kusage & (KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT)) == 0)) { + if (((util_X509_get_key_usage(candidate) & (KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT)) != 0) && + ((util_X509_get_key_usage(current) & (KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT)) == 0)) { return 0; } } @@ -693,7 +693,7 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert, goto done; } - issuerlen = i2d_X509_NAME(ca->cert_info->issuer, NULL); + issuerlen = i2d_X509_NAME(X509_get_issuer_name(ca), NULL); if (issuerlen < 0) { cm_log(1, "Error encoding CA certificate issuer name.\n"); goto done; @@ -704,12 +704,12 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert, goto done; } u = issuer; - if (i2d_X509_NAME(ca->cert_info->issuer, &u) != issuerlen) { + if (i2d_X509_NAME(X509_get_issuer_name(ca), &u) != issuerlen) { cm_log(1, "Error encoding CA certificate issuer name.\n"); goto done; } - subjectlen = i2d_X509_NAME(mini->cert_info->subject, NULL); + subjectlen = i2d_X509_NAME(X509_get_subject_name(mini), NULL); if (subjectlen < 0) { cm_log(1, "Error encoding client certificate subject name.\n"); goto done; @@ -720,7 +720,7 @@ cm_pkcs7_generate_ias(char *cacert, char *minicert, goto done; } u = subject; - if (i2d_X509_NAME(mini->cert_info->subject, &u) != subjectlen) { + if (i2d_X509_NAME(X509_get_subject_name(mini), &u) != subjectlen) { cm_log(1, "Error encoding client certificate subject name.\n"); goto done; } @@ -798,28 +798,22 @@ get_pstring_attribute(void *parent, STACK_OF(X509_ATTRIBUTE) *attrs, int nid) } for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { a = sk_X509_ATTRIBUTE_value(attrs, i); - if (OBJ_obj2nid(a->object) != nid) { + if (OBJ_obj2nid(util_X509_ATTRIBUTE_get0_object(a)) != nid) { continue; } - if (a->single) { - value = a->value.single; - } else { - if (sk_ASN1_TYPE_num(a->value.set) == 1) { - value = sk_ASN1_TYPE_value(a->value.set, 0); - } else { - value = NULL; - } - } - if ((value != NULL) && (value->type == V_ASN1_PRINTABLESTRING)) { - p = value->value.printablestring; - if (p != NULL) { - len = ASN1_STRING_length(p); - s = (const char *) ASN1_STRING_data(p); - ret = talloc_size(parent, len + 1); - if (ret != NULL) { - memcpy(ret, s, len); - ret[len] = '\0'; - return ret; + if (X509_ATTRIBUTE_count(a) > 0) { + value = X509_ATTRIBUTE_get0_type(a, 0); + if (value->type == V_ASN1_PRINTABLESTRING) { + p = value->value.printablestring; + if (p != NULL) { + len = util_ASN1_STRING_length(p); + s = (const char *) util_ASN1_STRING_get0_data(p); + ret = talloc_size(parent, len + 1); + if (ret != NULL) { + memcpy(ret, s, len); + ret[len] = '\0'; + return ret; + } } } } @@ -844,28 +838,22 @@ get_ostring_attribute(void *parent, STACK_OF(X509_ATTRIBUTE) *attrs, int nid, } for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { a = sk_X509_ATTRIBUTE_value(attrs, i); - if (OBJ_obj2nid(a->object) != nid) { + if (OBJ_obj2nid(util_X509_ATTRIBUTE_get0_object(a)) != nid) { continue; } - if (a->single) { - value = a->value.single; - } else { - if (sk_ASN1_TYPE_num(a->value.set) == 1) { - value = sk_ASN1_TYPE_value(a->value.set, 0); - } else { - value = NULL; - } - } - if ((value != NULL) && (value->type == V_ASN1_OCTET_STRING)) { - p = value->value.octet_string; - if (p != NULL) { - i = ASN1_STRING_length(p); - s = ASN1_STRING_data(p); - *ret = talloc_size(parent, i + 1); - if (*ret != NULL) { - memcpy(*ret, s, i); - *length = i; - return; + if (X509_ATTRIBUTE_count(a) > 0) { + value = X509_ATTRIBUTE_get0_type(a, 0); + if (value->type == V_ASN1_OCTET_STRING) { + p = value->value.octet_string; + if (p != NULL) { + i = util_ASN1_STRING_length(p); + s = util_ASN1_STRING_get0_data(p); + *ret = talloc_size(parent, i + 1); + if (*ret != NULL) { + memcpy(*ret, s, i); + *length = i; + return; + } } } } diff --git a/src/prefs-o.c b/src/prefs-o.c index 9835190..64542f8 100644 --- a/src/prefs-o.c +++ b/src/prefs-o.c @@ -26,6 +26,7 @@ #include #include +#include #include "prefs.h" #include "prefs.h" diff --git a/src/scepgen-n.c b/src/scepgen-n.c index 4a4dc4c..8f3c160 100644 --- a/src/scepgen-n.c +++ b/src/scepgen-n.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Red Hat, Inc. + * Copyright (C) 2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -63,6 +64,7 @@ #include "submit-u.h" #include "subproc.h" #include "util-n.h" +#include "util-o.h" struct cm_scepgen_state { struct cm_scepgen_state_pvt pvt; @@ -70,14 +72,51 @@ struct cm_scepgen_state { struct cm_subproc_state *subproc; }; +/* Ad-hoc. */ +static const SEC_ASN1Template +cm_scepgen_n_certattr_template[] = { + { + .kind = SEC_ASN1_SEQUENCE, + .offset = 0, + .sub = NULL, + .size = sizeof(CERTAttribute), + }, + { + .kind = SEC_ASN1_OBJECT_ID, + .offset = offsetof(CERTAttribute, attrType), + .sub = NULL, + .size = sizeof(SECItem), + }, + { + .kind = SEC_ASN1_SET_OF, + .offset = offsetof(CERTAttribute, attrValue), + .sub = &SEC_AnyTemplate, + .size = 0, + }, + {0, 0, NULL, 0}, +}; + +static const SEC_ASN1Template +cm_scepgen_n_set_of_certattr_template[] = { + { + .kind = SEC_ASN1_SET_OF, + .offset = 0, + .sub = cm_scepgen_n_certattr_template, + .size = 0, + }, +}; + static void cm_scepgen_n_resign(PKCS7 *p7, SECKEYPrivateKey *privkey) { - unsigned char *sabuf = NULL, *u; - int salen; - SECItem signature; + PLArenaPool *arena; + SECItem signature, item; SECOidTag digalg, sigalg; PKCS7_SIGNER_INFO *sinfo; + X509_ATTRIBUTE *a; + CERTAttribute **attr, aitem; + unsigned char *p, *q; + int len, auth_attr_count, i, j, l; if (p7 == NULL) { return; @@ -88,23 +127,45 @@ cm_scepgen_n_resign(PKCS7 *p7, SECKEYPrivateKey *privkey) } sinfo = sk_PKCS7_SIGNER_INFO_value(p7->d.sign->signer_info, 0); - salen = i2d_ASN1_SET_OF_X509_ATTRIBUTE(sinfo->auth_attr, NULL, - i2d_X509_ATTRIBUTE, - V_ASN1_SET, - V_ASN1_UNIVERSAL, - IS_SET); - sabuf = malloc(salen); - if (sabuf == NULL) { - cm_log(1, "Out of memory.\n"); + arena = PORT_NewArena(sizeof(double)); + if (arena == NULL) { + cm_log(1, "Out of memory re-signing data."); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - u = sabuf; - if (i2d_ASN1_SET_OF_X509_ATTRIBUTE(sinfo->auth_attr, &u, - i2d_X509_ATTRIBUTE, - V_ASN1_SET, - V_ASN1_UNIVERSAL, - IS_SET) != salen) { - cm_log(1, "Encoding error.\n"); + + auth_attr_count = X509at_get_attr_count(sinfo->auth_attr); + attr = PORT_ArenaZAlloc(arena, (auth_attr_count + 1) * sizeof(CERTAttribute*)); + for (i = j = 0; i < auth_attr_count; i++) { + a = X509at_get_attr(sinfo->auth_attr, i); + len = i2d_X509_ATTRIBUTE(a, NULL); + if (len < 0) { + cm_log(1, "Error determining size of X509 attribute."); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + p = q = malloc(len); + l = i2d_X509_ATTRIBUTE(a, &q); + if (l != len) { + cm_log(1, "Error encoding X509 attribute."); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + memset(&item, 0, sizeof(item)); + item.data = p; + item.len = len; + memset(&aitem, 0, sizeof(aitem)); + if (SEC_ASN1DecodeItem(arena, &aitem, cm_scepgen_n_certattr_template, &item) == SECSuccess) { + attr[j] = PORT_ArenaZAlloc(arena, sizeof(CERTAttribute)); + if (attr[j] == NULL) { + cm_log(1, "Out of memory copying X509 attribute."); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + *(attr[j]) = aitem; + j++; + } + free(p); + } + memset(&item, 0, sizeof(item)); + if (SEC_ASN1EncodeItem(arena, &item, &attr, cm_scepgen_n_set_of_certattr_template) != &item) { + cm_log(1, "Unable to encode signing attributes.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } memset(&signature, 0, sizeof(signature)); @@ -114,15 +175,14 @@ cm_scepgen_n_resign(PKCS7 *p7, SECKEYPrivateKey *privkey) cm_log(1, "Unable to match digest algorithm and key.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (SEC_SignData(&signature, sabuf, salen, privkey, + if (SEC_SignData(&signature, item.data, item.len, privkey, sigalg) != SECSuccess) { cm_log(1, "Error re-signing: %s.\n", PR_ErrorToName(PORT_GetError())); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - M_ASN1_OCTET_STRING_set(sinfo->enc_digest, - signature.data, signature.len); - free(sabuf); + util_ASN1_OCTET_STRING_set(sinfo->enc_digest, + signature.data, signature.len); } static int diff --git a/src/scepgen-o.c b/src/scepgen-o.c index 3a81b19..6e318e5 100644 --- a/src/scepgen-o.c +++ b/src/scepgen-o.c @@ -215,7 +215,7 @@ set_pkimessage_attrs(PKCS7 *p7, sinfo = sk_PKCS7_SIGNER_INFO_value(p7->d.sign->signer_info, 0); if (tx != NULL) { cm_log(1, "Setting transaction ID \"%s\".\n", tx); - t = M_ASN1_PRINTABLE_new(); + t = util_ASN1_PRINTABLESTRING_new(); if (t == NULL) { return; } @@ -225,7 +225,7 @@ set_pkimessage_attrs(PKCS7 *p7, } if (msgtype != NULL) { cm_log(1, "Setting message type \"%s\".\n", msgtype); - m = M_ASN1_PRINTABLE_new(); + m = util_ASN1_PRINTABLESTRING_new(); if (m == NULL) { return; } @@ -235,7 +235,7 @@ set_pkimessage_attrs(PKCS7 *p7, } if (pkistatus != NULL) { cm_log(1, "Setting pkiStatus \"%s\".\n", pkistatus); - p = M_ASN1_PRINTABLE_new(); + p = util_ASN1_PRINTABLESTRING_new(); if (p == NULL) { return; } @@ -245,7 +245,7 @@ set_pkimessage_attrs(PKCS7 *p7, } if (failinfo != NULL) { cm_log(1, "Setting failInfo \"%s\".\n", failinfo); - f = M_ASN1_PRINTABLE_new(); + f = util_ASN1_PRINTABLESTRING_new(); if (f == NULL) { return; } @@ -255,21 +255,21 @@ set_pkimessage_attrs(PKCS7 *p7, } if (sender_nonce != NULL) { cm_log(1, "Setting sender nonce.\n"); - s = ASN1_OCTET_STRING_new(); + s = util_ASN1_OCTET_STRING_new(); if (s == NULL) { return; } - M_ASN1_OCTET_STRING_set(s, sender_nonce, sender_nonce_length); + util_ASN1_OCTET_STRING_set(s, sender_nonce, sender_nonce_length); PKCS7_add_signed_attribute(sinfo, cm_scep_o_get_sender_nonce_nid(), V_ASN1_OCTET_STRING, s); } if (recipient_nonce != NULL) { cm_log(1, "Setting recipient nonce.\n"); - r = ASN1_OCTET_STRING_new(); + r = util_ASN1_OCTET_STRING_new(); if (r == NULL) { return; } - M_ASN1_OCTET_STRING_set(r, recipient_nonce, recipient_nonce_length); + util_ASN1_OCTET_STRING_set(r, recipient_nonce, recipient_nonce_length); PKCS7_add_signed_attribute(sinfo, cm_scep_o_get_recipient_nonce_nid(), V_ASN1_OCTET_STRING, r); @@ -499,8 +499,12 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry, if (old_cert != NULL) { /* Sign the data using the previously-issued certificate and * the matching key. */ - pubkey = X509_PUBKEY_get(old_cert->cert_info->key); - X509_PUBKEY_set(&old_cert->cert_info->key, old_pkey); + pubkey = util_public_EVP_PKEY_dup(util_X509_get0_pubkey(old_cert)); + if (pubkey == NULL) { + cm_log(1, "Error generating PKCSREQ pkiMessage: error copying key.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + util_X509_set_pubkey(old_cert, old_pkey); cm_log(1, "Generating PKCSREQ pkiMessage.\n"); *csr_old = build_pkimessage(old_pkey, old_cert, chain, digest, csr, csr_length, @@ -518,15 +522,20 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry, nonce, nonce_length, NULL, 0); cm_log(1, "Signing using previously-issued key and cert.\n"); - X509_PUBKEY_set(&old_cert->cert_info->key, pubkey); + util_X509_set_pubkey(old_cert, pubkey); + EVP_PKEY_free(pubkey); X509_free(old_cert); } else { if (new_pkey == NULL) { /* Sign the data using the old key and the mini certificate, * since we may not have a previously-issued certificate (and * if we do, we did that in another code path. */ - pubkey = X509_PUBKEY_get(new_cert->cert_info->key); - X509_PUBKEY_set(&new_cert->cert_info->key, old_pkey); + pubkey = util_public_EVP_PKEY_dup(util_X509_get0_pubkey(new_cert)); + if (pubkey == NULL) { + cm_log(1, "Error generating PKCSREQ pkiMessage: error copying key.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + util_X509_set_pubkey(new_cert, old_pkey); cm_log(1, "Generating PKCSREQ pkiMessage.\n"); *csr_old = build_pkimessage(old_pkey, new_cert, chain, digest, csr, csr_length, @@ -544,7 +553,8 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry, nonce, nonce_length, NULL, 0); cm_log(1, "Signing using old key.\n"); - X509_PUBKEY_set(&new_cert->cert_info->key, pubkey); + util_X509_set_pubkey(new_cert, pubkey); + EVP_PKEY_free(pubkey); } else { /* No cert, and the minicert matches the new key. */ *csr_old = NULL; @@ -554,8 +564,12 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry, if (new_pkey != NULL) { /* Sign the data using the new key and mini certificate, since * any previously-issued certificate won't match. */ - pubkey = X509_PUBKEY_get(new_cert->cert_info->key); - X509_PUBKEY_set(&new_cert->cert_info->key, new_pkey); + pubkey = util_public_EVP_PKEY_dup(util_X509_get0_pubkey(new_cert)); + if (pubkey == NULL) { + cm_log(1, "Error generating rekeying PKCSREQ pkiMessage: error copying key.\n"); + _exit(CM_SUB_STATUS_INTERNAL_ERROR); + } + util_X509_set_pubkey(new_cert, new_pkey); cm_log(1, "Generating rekeying PKCSREQ pkiMessage.\n"); *csr_new = build_pkimessage(new_pkey, new_cert, chain, digest, csr, csr_length, @@ -573,7 +587,8 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry, nonce, nonce_length, NULL, 0); cm_log(1, "Signing using new key.\n"); - X509_PUBKEY_set(&new_cert->cert_info->key, pubkey); + util_X509_set_pubkey(new_cert, pubkey); + EVP_PKEY_free(pubkey); } else { *csr_new = NULL; *ias_new = NULL; @@ -633,8 +648,8 @@ cm_scepgen_o_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry, } else { new_pkey = NULL; } - if ((EVP_PKEY_type(old_pkey->type) != EVP_PKEY_RSA) || - ((new_pkey != NULL) && (EVP_PKEY_type(new_pkey->type) != EVP_PKEY_RSA))) { + if ((util_EVP_PKEY_base_id(old_pkey) != EVP_PKEY_RSA) || + ((new_pkey != NULL) && (util_EVP_PKEY_base_id(new_pkey) != EVP_PKEY_RSA))) { cm_log(1, "Keys aren't RSA. They won't work with SCEP.\n"); _exit(CM_SUB_STATUS_ERROR_KEY_TYPE); } diff --git a/src/submit-n.c b/src/submit-n.c index 7151bab..872153e 100644 --- a/src/submit-n.c +++ b/src/submit-n.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -71,8 +72,8 @@ cm_submit_n_tag_from_nid(int nid) obj = OBJ_nid2obj(nid); if (obj != NULL) { memset(&oid, 0, sizeof(oid)); - oid.data = (unsigned char *) obj->data; - oid.len = obj->length; + oid.data = (unsigned char *) util_OBJ_get0_data(obj); + oid.len = util_OBJ_length(obj); return SECOID_FindOIDTag(&oid); } else { return SEC_OID_UNKNOWN; @@ -97,7 +98,7 @@ try_to_decode(void *parent, PLArenaPool *arena, SECItem *item, RSA *rsa = NULL; char buf[BUFSIZ]; const unsigned char *u; - unsigned char *enc_key, *dec, *reenc; + unsigned char *enc_key, *dec, *reenc, *param_data; unsigned int enc_key_len, dec_len; ssize_t reenc_len; long error, l; @@ -138,14 +139,25 @@ try_to_decode(void *parent, PLArenaPool *arena, SECItem *item, if (p7i->key_enc_algor->parameter->type == V_ASN1_OCTET_STRING) { params = p7i->key_enc_algor->parameter->value.octet_string; memset(¶m, 0, sizeof(param)); - param.data = M_ASN1_STRING_data(params); - param.len = M_ASN1_STRING_length(params); + param.len = util_ASN1_STRING_length(params); + param_data = PORT_ArenaZAlloc(arena, param.len); + if (param_data == NULL) { + cm_log(1, "Out of memory decrypting bulk key.\n"); + goto done; + } + memcpy(param_data, util_ASN1_STRING_get0_data(params), param.len); + param.data = param_data; parameters = ¶m; } else { parameters = NULL; } - enc_key = M_ASN1_STRING_data(p7i->enc_key); - enc_key_len = M_ASN1_STRING_length(p7i->enc_key); + enc_key_len = util_ASN1_STRING_length(p7i->enc_key); + enc_key = PORT_ArenaZAlloc(arena, enc_key_len); + if (enc_key == NULL) { + cm_log(1, "Out of memory decrypting bulk key.\n"); + goto done; + } + memcpy(enc_key, util_ASN1_STRING_get0_data(p7i->enc_key), enc_key_len); dec_len = enc_key_len + BUFSIZ; dec = talloc_size(parent, dec_len); if (parameters == NULL) { @@ -216,7 +228,7 @@ retry_gen: /* Set the new encrypted bulk key. */ p7i->key_enc_algor->algorithm = OBJ_dup(OBJ_nid2obj(NID_rsaEncryption)); ASN1_TYPE_set(p7i->key_enc_algor->parameter, V_ASN1_NULL, NULL); - M_ASN1_OCTET_STRING_set(p7i->enc_key, reenc, reenc_len); + util_ASN1_OCTET_STRING_set(p7i->enc_key, reenc, reenc_len); /* And now, finally, decrypt the payload. */ out = BIO_new(BIO_s_mem()); diff --git a/src/submit-o.c b/src/submit-o.c index 8fbeb17..d44dc2d 100644 --- a/src/submit-o.c +++ b/src/submit-o.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009,2010,2011,2012,2014.2015 Red Hat, Inc. + * Copyright (C) 2009,2010,2011,2012,2014,2015,2017 Red Hat, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,14 +26,19 @@ #include #include -#include -#include - #include #include #include #include +#include +#include +#include +#include +#include +#include +#include + #include #include @@ -52,6 +57,149 @@ #include "subproc.h" #include "util-o.h" +static void +cm_submit_o_set_things(X509 **cert, X509 *signer, unsigned char uuid[16], unsigned int uuid_len, + STACK_OF(X509_EXTENSION) *extensions) +{ + PLArenaPool *arena = NULL; + CERTCertificate subject, issuer; + CERTSignedData scert; + SECItem item, *encoded; + unsigned char *p, *q; + const unsigned char *d; + int length, l; + + arena = PORT_NewArena(sizeof(double)); + if (arena == NULL) { + cm_log(1, "Out of memory for decoding cert_info."); + return; + } + memset(&item, 0, sizeof(item)); + + if (signer != NULL) { + length = i2d_X509(signer, NULL); + if (length < 0) { + cm_log(1, "Error encoding signer cert."); + PORT_FreeArena(arena, PR_TRUE); + return; + } + p = q = malloc(length); + l = i2d_X509(signer, &q); + if (l != length) { + cm_log(1, "Error encoding signer cert: %d != %d.", l, length); + free(p); + PORT_FreeArena(arena, PR_TRUE); + return; + } + memset(&scert, 0, sizeof(scert)); + item.data = p; + item.len = length; + if (SEC_ASN1DecodeItem(arena, &scert, CERT_SignedDataTemplate, &item) != SECSuccess) { + cm_log(1, "Error decoding signer cert: %s.", PR_ErrorToName(PORT_GetError())); + free(p); + PORT_FreeArena(arena, PR_TRUE); + return; + } + memset(&issuer, 0, sizeof(issuer)); + if (SEC_ASN1DecodeItem(arena, &issuer, CERT_CertificateTemplate, &scert.data) != SECSuccess) { + cm_log(1, "Error decoding signer cert info: %s.", PR_ErrorToName(PORT_GetError())); + free(p); + PORT_FreeArena(arena, PR_TRUE); + return; + } + free(p); + } + + length = i2d_X509(*cert, NULL); + if (length < 0) { + cm_log(1, "Error encoding cert."); + PORT_FreeArena(arena, PR_TRUE); + return; + } + p = q = malloc(length); + l = i2d_X509(*cert, &q); + if (l != length) { + cm_log(1, "Error encoding cert: %d != %d.", l, length); + free(p); + PORT_FreeArena(arena, PR_TRUE); + return; + } + memset(&scert, 0, sizeof(scert)); + item.data = p; + item.len = length; + if (SEC_ASN1DecodeItem(arena, &scert, CERT_SignedDataTemplate, &item) != SECSuccess) { + cm_log(1, "Error decoding cert: %s.", PR_ErrorToName(PORT_GetError())); + free(p); + PORT_FreeArena(arena, PR_TRUE); + return; + } + memset(&subject, 0, sizeof(subject)); + if (SEC_ASN1DecodeItem(arena, &subject, CERT_CertificateTemplate, &scert.data) != SECSuccess) { + cm_log(1, "Error decoding cert info: %s.", PR_ErrorToName(PORT_GetError())); + free(p); + PORT_FreeArena(arena, PR_TRUE); + return; + } + free(p); + + memset(&subject.issuerID, 0, sizeof(subject.issuerID)); + memset(&subject.subjectID, 0, sizeof(subject.subjectID)); + if (uuid_len > 0) { + subject.subjectID.data = uuid; + subject.subjectID.len = uuid_len; + if (signer != NULL) { + subject.issuerID = issuer.subjectID; + } else { + subject.issuerID.data = uuid; + subject.issuerID.len = uuid_len; + } + } + + length = i2d_X509_EXTENSIONS(extensions, NULL); + p = q = malloc(length); + l = i2d_X509_EXTENSIONS(extensions, &q); + if (l != length) { + cm_log(1, "Error encoding extensions: %d != %d.", l, length); + free(p); + PORT_FreeArena(arena, PR_TRUE); + return; + } + item.data = p; + item.len = length; + if (SEC_ASN1DecodeItem(arena, &subject.extensions, CERT_SequenceOfCertExtensionTemplate, &item) != SECSuccess) { + cm_log(1, "Error decoding extensions: %s.", PR_ErrorToName(PORT_GetError())); + free(p); + PORT_FreeArena(arena, PR_TRUE); + return; + } + free(p); + + memset(&scert.data, 0, sizeof(scert.data)); + encoded = SEC_ASN1EncodeItem(arena, &scert.data, &subject, CERT_CertificateTemplate); + if (encoded != &scert.data) { + cm_log(1, "Error re-encoding cert_info: %s.", PR_ErrorToName(PORT_GetError())); + PORT_FreeArena(arena, PR_TRUE); + return; + } + memset(&item, 0, sizeof(item)); + encoded = SEC_ASN1EncodeItem(arena, &item, &scert, CERT_SignedDataTemplate); + if (encoded != &item) { + cm_log(1, "Error re-encoding cert: %s.", PR_ErrorToName(PORT_GetError())); + PORT_FreeArena(arena, PR_TRUE); + return; + } + + d = item.data; + *cert = d2i_X509(NULL, &d, item.len); + if (*cert == NULL) { + cm_log(1, "Error re-decoding cert."); + PORT_FreeArena(arena, PR_TRUE); + return; + } + + PORT_FreeArena(arena, PR_TRUE); +} + int cm_submit_o_sign(void *parent, char *csr, X509 *signer, EVP_PKEY *signer_key, @@ -61,6 +209,7 @@ cm_submit_o_sign(void *parent, char *csr, X509_REQ *req; BIO *bio; ASN1_INTEGER *seriali; + ASN1_TIME *not_before, *not_after; BASIC_CONSTRAINTS *basic; ASN1_OCTET_STRING *skid; AUTHORITY_KEYID akid; @@ -68,10 +217,8 @@ cm_submit_o_sign(void *parent, char *csr, const unsigned char *serialtmp, *basictmp; char *serial; int status = CM_SUBMIT_STATUS_WAIT, seriall, basicl, crit, i; - unsigned int mdlen; -#ifdef HAVE_UUID + unsigned int mdlen, uuid_len; unsigned char uuid[16]; -#endif bio = BIO_new_mem_buf(csr, -1); if (bio != NULL) { @@ -82,18 +229,21 @@ cm_submit_o_sign(void *parent, char *csr, if (*cert != NULL) { X509_set_subject_name(*cert, X509_REQ_get_subject_name(req)); if (signer != NULL) { - X509_set_issuer_name(*cert, signer->cert_info->subject); + X509_set_issuer_name(*cert, X509_get_subject_name(signer)); } else { X509_set_issuer_name(*cert, X509_REQ_get_subject_name(req)); } - X509_set_pubkey(*cert, X509_PUBKEY_get(req->req_info->pubkey)); - ASN1_TIME_set((*cert)->cert_info->validity->notBefore, now); + X509_set_pubkey(*cert, util_X509_REQ_get0_pubkey(req)); + not_before = util_ASN1_TIME_new(); + ASN1_TIME_set(not_before, now); + util_X509_set1_notBefore(*cert, not_before); if ((life == 0) && (signer != NULL)) { - (*cert)->cert_info->validity->notAfter = - M_ASN1_TIME_dup(signer->cert_info->validity->notAfter); + not_after = util_ASN1_TIME_dup((ASN1_TIME *)util_X509_get0_notAfter(signer)); } else { - ASN1_TIME_set((*cert)->cert_info->validity->notAfter, now + life); + not_after = util_ASN1_TIME_new(); + ASN1_TIME_set(not_after, now + life); } + util_X509_set1_notAfter(*cert, not_after); X509_set_version(*cert, 2); /* set the serial number */ cm_log(3, "Setting certificate serial number \"%s\".\n", @@ -105,28 +255,19 @@ cm_submit_o_sign(void *parent, char *csr, serialtmp = seriald; seriali = d2i_ASN1_INTEGER(NULL, &serialtmp, seriall); X509_set_serialNumber(*cert, seriali); + uuid_len = 0; #ifdef HAVE_UUID if (cm_prefs_populate_unique_id()) { if (cm_submit_uuid_new(uuid) == 0) { - (*cert)->cert_info->subjectUID = M_ASN1_BIT_STRING_new(); - if ((*cert)->cert_info->subjectUID != NULL) { - ASN1_BIT_STRING_set((*cert)->cert_info->subjectUID, uuid, 16); - } - if (signer != NULL) { - if (signer->cert_info->subjectUID != NULL) { - (*cert)->cert_info->issuerUID = M_ASN1_BIT_STRING_dup(signer->cert_info->subjectUID); - } - } else { - (*cert)->cert_info->issuerUID = M_ASN1_BIT_STRING_new(); - if ((*cert)->cert_info->issuerUID != NULL) { - ASN1_BIT_STRING_set((*cert)->cert_info->issuerUID, uuid, 16); - } - } + uuid_len = sizeof(uuid); } } #endif + /* Add a signature so that it looks right...ish. */ + X509_sign(*cert, signer_key, cm_prefs_ossl_hash()); + cm_submit_o_set_things(cert, signer, uuid, uuid_len, + X509_REQ_get_extensions(req)); /* add basic constraints if needed */ - (*cert)->cert_info->extensions = X509_REQ_get_extensions(req); i = X509_get_ext_by_NID(*cert, NID_basic_constraints, -1); if (i == -1) { basicl = strlen(CM_BASIC_CONSTRAINT_NOT_CA) / 2; @@ -147,8 +288,8 @@ cm_submit_o_sign(void *parent, char *csr, i = X509_get_ext_by_NID(*cert, NID_subject_key_identifier, -1); if (i == -1) { if (X509_pubkey_digest(*cert, EVP_sha1(), md, &mdlen)) { - skid = M_ASN1_OCTET_STRING_new(); - M_ASN1_OCTET_STRING_set(skid, md, mdlen); + skid = util_ASN1_OCTET_STRING_new(); + util_ASN1_OCTET_STRING_set(skid, md, mdlen); X509_add1_ext_i2d(*cert, NID_subject_key_identifier, skid, 0, 0); } } @@ -161,18 +302,15 @@ cm_submit_o_sign(void *parent, char *csr, status = CM_SUBMIT_STATUS_UNREACHABLE; } } else { - cm_log(1, "Error building " - "template certificate.\n"); + cm_log(1, "Error building template certificate.\n"); status = CM_SUBMIT_STATUS_REJECTED; } } else { - cm_log(1, "Error reading " - "signing request.\n"); + cm_log(1, "Error reading signing request.\n"); } BIO_free(bio); } else { - cm_log(1, "Error parsing signing " - "request.\n"); + cm_log(1, "Error parsing signing request.\n"); } return status; } diff --git a/src/util-o.c b/src/util-o.c index e187890..dc515c6 100644 --- a/src/util-o.c +++ b/src/util-o.c @@ -33,7 +33,10 @@ #include #include +#include #include +#include +#include #include "cm.h" #include "log.h" @@ -171,3 +174,423 @@ util_o_cert_cmp(const void *a, const void *b) return X509_cmp(*x, *y); } #endif + +ASN1_BIT_STRING * +util_ASN1_BIT_STRING_new(void) +{ +#ifdef HAVE_ASN1_BIT_STRING_NEW + return ASN1_BIT_STRING_new(); +#else + return M_ASN1_BIT_STRING_new(); +#endif +} + +ASN1_GENERALIZEDTIME * +util_ASN1_GENERALIZEDTIME_new(void) +{ +#ifdef HAVE_ASN1_GENERALIZEDTIME_NEW + return ASN1_GENERALIZEDTIME_new(); +#else + return M_ASN1_GENERALIZEDTIME_new(); +#endif +} + +ASN1_IA5STRING * +util_ASN1_IA5STRING_new(void) +{ +#ifdef HAVE_ASN1_IA5STRING_NEW + return ASN1_IA5STRING_new(); +#else + return M_ASN1_IA5STRING_new(); +#endif +} + +ASN1_INTEGER * +util_ASN1_INTEGER_new(void) +{ +#ifdef HAVE_ASN1_INTEGER_NEW + return ASN1_INTEGER_new(); +#else + return M_ASN1_INTEGER_new(); +#endif +} + +ASN1_OCTET_STRING * +util_ASN1_OCTET_STRING_new(void) +{ +#ifdef HAVE_ASN1_OCTET_STRING_NEW + return ASN1_OCTET_STRING_new(); +#else + return M_ASN1_OCTET_STRING_new(); +#endif +} + +int +util_ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len) +{ +#ifdef HAVE_ASN1_OCTET_STRING_SET + return ASN1_OCTET_STRING_set(str, data, len); +#else + return M_ASN1_OCTET_STRING_set(str, data, len); +#endif +} + +ASN1_PRINTABLESTRING * +util_ASN1_PRINTABLESTRING_new(void) +{ +#ifdef HAVE_ASN1_PRINTABLESTRING_NEW + return ASN1_PRINTABLESTRING_new(); +#else + return M_ASN1_PRINTABLESTRING_new(); +#endif +} + +const unsigned char * +util_ASN1_STRING_get0_data(const ASN1_STRING *x) +{ +#ifdef HAVE_ASN1_STRING_GET0_DATA + return ASN1_STRING_get0_data(x); +#elif defined(HAVE_ASN1_STRING_GET_DATA) + return ASN1_STRING_get_data(x); +#else + return M_ASN1_STRING_data(x); +#endif +} + +int +util_ASN1_STRING_length(const ASN1_STRING *x) +{ +#ifdef HAVE_ASN1_STRING_LENGTH + return ASN1_STRING_length(x); +#else + return M_ASN1_STRING_length(x); +#endif +} + +ASN1_STRING * +util_ASN1_STRING_new(void) +{ +#ifdef HAVE_ASN1_STRING_NEW + return ASN1_STRING_new(); +#else + return M_ASN1_STRING_new(); +#endif +} + +ASN1_TIME * +util_ASN1_TIME_dup(ASN1_TIME *t) +{ + unsigned char *p, *pp; + const unsigned char *cp; + long len; + + len = i2d_ASN1_TIME(t, NULL); + p = malloc(len); + if (p != NULL) { + pp = p; + if (i2d_ASN1_TIME(t, &pp) < 0) { + free(p); + return NULL; + } + cp = p; + t = d2i_ASN1_TIME(NULL, &cp, len); + if (cp - p != len) { + t = NULL; + } + free(p); + return t; + } + return NULL; +} + +ASN1_TIME * +util_ASN1_TIME_new(void) +{ +#ifdef HAVE_ASN1_TIME_NEW + return ASN1_TIME_new(); +#else + return M_ASN1_TIME_new(); +#endif +} + +ASN1_TIME * +util_ASN1_TIME_set(ASN1_TIME *str, time_t t) +{ +#ifdef HAVE_ASN1_TIME_SET + return ASN1_TIME_set(str, t); +#else + return M_ASN1_TIME_set(str, t); +#endif +} + +int +util_EVP_PKEY_id(const EVP_PKEY *pkey) +{ +#ifdef HAVE_EVP_PKEY_ID + return EVP_PKEY_id(pkey); +#else + return pkey->type; +#endif +} + +int +util_EVP_PKEY_base_id(const EVP_PKEY *pkey) +{ +#ifdef HAVE_EVP_PKEY_BASE_ID + return EVP_PKEY_base_id(pkey); +#else + return EVP_PKEY_type(util_EVP_PKEY_id(pkey)); +#endif +} + +const unsigned char * +util_OBJ_get0_data(const ASN1_OBJECT *obj) +{ +#ifdef HAVE_OBJ_GET0_DATA + return OBJ_get0_data(obj); +#else + return obj->data; +#endif +} + +size_t +util_OBJ_length(const ASN1_OBJECT *obj) +{ +#ifdef HAVE_OBJ_LENGTH + return OBJ_length(obj); +#else + return obj->length; +#endif +} + +ASN1_OBJECT * +util_X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *a) +{ +#ifdef HAVE_X509_ATTRIBUTE_GET0_OBJECT + return X509_ATTRIBUTE_get0_object(a); +#else + return a->object; +#endif +} + +const ASN1_TIME * +util_X509_get0_notAfter(X509 *x) +{ +#ifdef HAVE_X509_GET0_NOTAFTER + return X509_get0_notAfter(x); +#else + return x->cert_info->validity->notAfter; +#endif +} + +EVP_PKEY * +util_X509_get0_pubkey(X509 *cert) +{ +#ifdef HAVE_X509_GET0_PUBKEY + return X509_get0_pubkey(cert); +#else + return X509_PUBKEY_get(cert->cert_info->key); +#endif +} + +const ASN1_INTEGER * +util_X509_get0_serialNumber(X509 *cert) +{ +#ifdef HAVE_X509_GET0_SERIALNUMBER + return X509_get0_serialNumber(cert); +#else + return cert->cert_info->serialNumber; +#endif +} + +X509_NAME * +util_X509_get0_issuer_name(X509 *x) +{ +#ifdef HAVE_X509_GET_ISSUER_NAME + return X509_get_issuer_name(x); +#else + return x->cert_info->issuer; +#endif +} + +uint32_t +util_X509_get_key_usage(X509 *x) +{ +#ifdef HAVE_X509_GET_KEY_USAGE + return X509_get_key_usage(x); +#else + return x->ex_kusage; +#endif +} + +X509_NAME * +util_X509_get0_subject_name(X509 *x) +{ +#ifdef HAVE_X509_GET_SUBJECT_NAME + return X509_get_subject_name(x); +#else + return x->cert_info->subject; +#endif +} + +EVP_PKEY * +util_X509_REQ_get0_pubkey(X509_REQ *req) +{ +#ifdef HAVE_X509_REQ_GET0_PUBKEY + return X509_REQ_get0_pubkey(req); +#else + return X509_PUBKEY_get(req->req_info->pubkey); +#endif +} + +void +util_X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg) +{ +#ifdef HAVE_X509_REQ_GET0_SIGNATURE + X509_REQ_get0_signature(req, psig, palg); +#else + if (psig != NULL) { + *psig = req->signature; + } + if (palg != NULL) { + *palg = req->sig_alg; + } +#endif +} + +int +util_X509_set_pubkey(X509 *cert, EVP_PKEY *pkey) +{ + return X509_set_pubkey(cert, pkey); +} + +int +util_X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name) +{ +#ifdef HAVE_X509_REQ_SET_SUBJECT_NAME + return X509_REQ_set_subject_name(req, name); +#else + return X509_NAME_set(&req->req_info->subject, name); +#endif +} + +int +util_X509_set1_notAfter(X509 *x, ASN1_TIME *tm) +{ +#ifdef HAVE_X509_SET1_NOTAFTER + return X509_set1_notAfter(x, tm); +#else + if (x != NULL) { + x->cert_info->validity->notAfter = tm; + return 1; + } + return 0; +#endif +} + +int +util_X509_set1_notBefore(X509 *x, ASN1_TIME *tm) +{ +#ifdef HAVE_X509_SET1_NOTBEFORE + return X509_set1_notBefore(x, tm); +#else + if (x != NULL) { + x->cert_info->validity->notBefore = tm; + return 1; + } + return 0; +#endif +} + +int +util_X509_set_issuer_name(X509 *x, X509_NAME *name) +{ +#ifdef HAVE_X509_SET_ISSUER_NAME + return X509_set_issuer_name(x, name); +#else + return X509_NAME_set(&x->cert_info->issuer, name); +#endif +} + +int +util_X509_set_subject_name(X509 *x, X509_NAME *name) +{ +#ifdef HAVE_X509_SET_SUBJECT_NAME + return X509_set_subject_name(x, name); +#else + return X509_NAME_set(&x->cert_info->subject, name); +#endif +} + +int +util_X509_set1_version(X509 *x, ASN1_INTEGER *version) +{ +#ifdef HAVE_X509_CERT_INFO + x->cert_info->version = ASN1_INTEGER_dup(version); + return x->cert_info->version != NULL; +#else + return X509_set_version(x, ASN1_INTEGER_get(version)); +#endif +} + +void +util_NETSCAPE_SPKI_set_sig_alg(NETSCAPE_SPKI *spki, const X509_ALGOR *sig_alg) +{ +#ifdef CM_NETSCAPE_SPKI_SIG_ALGOR_IS_POINTER + spki->sig_algor = X509_ALGOR_dup((X509_ALGOR *)sig_alg); +#else + spki->sig_algor = *X509_ALGOR_dup((X509_ALGOR *)sig_alg); +#endif +} + +static EVP_PKEY * +util_EVP_PKEY_dup(EVP_PKEY *pkey, + int (*i2d)(EVP_PKEY *, unsigned char **), + EVP_PKEY *(*d2i)(int, EVP_PKEY **, const unsigned char **, long)) +{ + EVP_PKEY *k; + unsigned char *p, *q; + const unsigned char *d; + int l, len; + + l = i2d(pkey, NULL); + if (l < 0) { + cm_log(1, "Error determining size of key."); + return NULL; + } + p = q = malloc(l); + if (p == NULL) { + cm_log(1, "Out of memory copying key."); + return NULL; + } + len = i2d(pkey, &q); + if (len != l) { + cm_log(1, "Unexpected error copying key."); + memset(p, 0, l); + free(p); + return NULL; + } + d = p; + k = d2i(util_EVP_PKEY_base_id(pkey), NULL, &d, len); + memset(p, 0, l); + free(p); + if (k == NULL) { + cm_log(1, "Unexpected error decoding copy of key."); + return NULL; + } + return k; +} + +EVP_PKEY * +util_public_EVP_PKEY_dup(EVP_PKEY *pkey) +{ + return util_EVP_PKEY_dup(pkey, i2d_PublicKey, d2i_PublicKey); +} + +EVP_PKEY * +util_private_EVP_PKEY_dup(EVP_PKEY *pkey) +{ + return util_EVP_PKEY_dup(pkey, i2d_PrivateKey, d2i_PrivateKey); +} diff --git a/src/util-o.h b/src/util-o.h index c2ea3ef..916777b 100644 --- a/src/util-o.h +++ b/src/util-o.h @@ -35,4 +35,41 @@ int util_o_cert_cmp(const X509 *const *a, const X509 *const *b); int util_o_cert_cmp(const void *a, const void *b); #endif +ASN1_BIT_STRING *util_ASN1_BIT_STRING_new(void); +ASN1_GENERALIZEDTIME *util_ASN1_GENERALIZEDTIME_new(void); +ASN1_IA5STRING *util_ASN1_IA5STRING_new(void); +ASN1_INTEGER *util_ASN1_INTEGER_new(void); +ASN1_OCTET_STRING *util_ASN1_OCTET_STRING_new(void); +int util_ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len); +ASN1_PRINTABLESTRING *util_ASN1_PRINTABLESTRING_new(void); +const unsigned char *util_ASN1_STRING_get0_data(const ASN1_STRING *x); +int util_ASN1_STRING_length(const ASN1_STRING *x); +ASN1_STRING *util_ASN1_STRING_new(void); +ASN1_TIME *util_ASN1_TIME_dup(ASN1_TIME *t); +ASN1_TIME *util_ASN1_TIME_new(void); +ASN1_TIME *util_ASN1_TIME_set(ASN1_TIME *str, time_t t); +int util_EVP_PKEY_base_id(const EVP_PKEY *pkey); +int util_EVP_PKEY_id(const EVP_PKEY *pkey); +const unsigned char *util_OBJ_get0_data(const ASN1_OBJECT *obj); +size_t util_OBJ_length(const ASN1_OBJECT *obj); +ASN1_OBJECT *util_X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *a); +const ASN1_TIME *util_X509_get0_notAfter(X509 *x); +EVP_PKEY *util_X509_get0_pubkey(X509 *cert); +const ASN1_INTEGER *util_X509_get0_serialNumber(X509 *cert); +X509_NAME *util_X509_get0_issuer_name(X509 *x); +uint32_t util_X509_get_key_usage(X509 *x); +X509_NAME *util_X509_get0_subject_name(X509 *x); +EVP_PKEY *util_X509_REQ_get0_pubkey(X509_REQ *req); +void util_X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, const X509_ALGOR **palg); +int util_X509_set_pubkey(X509 *cert, EVP_PKEY *pkey); +int util_X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); +int util_X509_set1_notAfter(X509 *x, ASN1_TIME *tm); +int util_X509_set1_notBefore(X509 *x, ASN1_TIME *tm); +int util_X509_set_issuer_name(X509 *x, X509_NAME *name); +int util_X509_set_subject_name(X509 *x, X509_NAME *name); +int util_X509_set1_version(X509 *x, ASN1_INTEGER *version); +void util_NETSCAPE_SPKI_set_sig_alg(NETSCAPE_SPKI *spki, const X509_ALGOR *sig_alg); +EVP_PKEY *util_public_EVP_PKEY_dup(EVP_PKEY *pkey); +EVP_PKEY *util_private_EVP_PKEY_dup(EVP_PKEY *pkey); + #endif From 4a190f68887bbdb8cd1e891900cbaca2c5f6d45d Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 14/22] Fix warning excess elements in struct initializer src/main.c: In function 'main': src/main.c:80:75: warning: excess elements in struct initializer {"fork", 'f', POPT_ARG_NONE, NULL, 'f', N_("do become a daemon"), NULL, NULL}, ^~~~ src/main.c:80:75: note: (near initialization for 'popts[6]') Signed-off-by: Nalin Dahyabhai --- diff --git a/src/main.c b/src/main.c index db7bd4d..68173a4 100644 --- a/src/main.c +++ b/src/main.c @@ -77,7 +77,7 @@ main(int argc, const char **argv) {"only-listening-socket", 'L', POPT_ARG_NONE, NULL, 'L', N_("only use a dedicated listening socket"), NULL}, {"listening-socket-path", 'P', POPT_ARG_STRING, &path, 0, N_("specify the dedicated listening socket"), N_("PATHNAME")}, {"nofork", 'n', POPT_ARG_NONE, NULL, 'n', N_("don't become a daemon"), NULL}, - {"fork", 'f', POPT_ARG_NONE, NULL, 'f', N_("do become a daemon"), NULL, NULL}, + {"fork", 'f', POPT_ARG_NONE, NULL, 'f', N_("do become a daemon"), NULL}, {"bus-activation-timeout", 'b', POPT_ARG_INT, NULL, 'b', N_("bus-activated, idle timeout"), N_("SECONDS")}, {"no-bus-activation-timeout", 'B', POPT_ARG_NONE, NULL, 'B', N_("don't use an idle timeout"), NULL}, {"debug-level", 'd', POPT_ARG_INT, NULL, 'd', N_("set debugging level (implies -n)"), N_("NUMBER")}, From a50519df4db6bf9d91f02c7832e9ddf7ad8be11b Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 15/22] Fix warning passing argument from incompatible pointer type src/submit-x.c: In function 'main': src/submit-x.c:946:38: warning: passing argument 3 of 'xmlrpc_read_i8' from incompatible pointer type xmlrpc_read_i8(&ctx->xenv, arg, &i8); ^ In file included from /usr/include/xmlrpc-c/client.h:15:0, from src/submit-x.c:30: /usr/include/xmlrpc-c/base.h:186:1: note: expected 'xmlrpc_int64 * const' but argument is of type 'int64_t *' xmlrpc_read_i8(xmlrpc_env * const envP, ^ src/submit-x.c:978:41: warning: passing argument 3 of 'xmlrpc_read_i8' from incompatible pointer type xmlrpc_read_i8(&ctx->xenv, val, &i8); ^ In file included from /usr/include/xmlrpc-c/client.h:15:0, from src/submit-x.c:30: /usr/include/xmlrpc-c/base.h:186:1: note: expected 'xmlrpc_int64 * const' but argument is of type 'int64_t *' xmlrpc_read_i8(xmlrpc_env * const envP, ^ Signed-off-by: Nalin Dahyabhai --- diff --git a/src/submit-x.c b/src/submit-x.c index a5f1c6f..60bcf78 100644 --- a/src/submit-x.c +++ b/src/submit-x.c @@ -761,7 +761,7 @@ int main(int argc, const char **argv) { int i, j, c, ret, k5 = FALSE, make_ccache = TRUE, verbose = 0; - int64_t i8; + xmlrpc_int64 i8; int32_t i32; const char *uri = NULL, *method = NULL, *ktname = NULL, *kpname = NULL; const char *s, *cainfo = NULL, *capath = NULL, *csrfile, *dictval; From 245cec221fd0abc7531083904ebf44abe29b857b Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Feb 23 2017 17:02:39 +0000 Subject: [PATCH 16/22] Include missing header file The header file stdint.h was probably included by other header file on fedora. In file included from src/ipa.c:41:0: src/srvloc.h:23:2: error: unknown type name 'uint16_t' uint16_t port; configure was executed with following parameters CFLAGS='-O2 -g -pipe -Wall -Werror=format-security -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Wall -Wextra -Wno-unused-parameter -g3 -O0' --libexecdir=/usr/lib --with-tmpdir=/var/run/certmonger --enable-systemd --enable-pie --enable-now --enable-tmpfiles Signed-off-by: Nalin Dahyabhai --- diff --git a/src/srvloc.h b/src/srvloc.h index 99c5b0f..1d07543 100644 --- a/src/srvloc.h +++ b/src/srvloc.h @@ -18,6 +18,8 @@ #ifndef cmsrvloc_h #define cmsrvloc_h +#include + struct cm_srvloc { char *host; uint16_t port; From fa8b8f0375460ddaf3d1a6bc550e0a7bca58bcd0 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Feb 23 2017 17:02:40 +0000 Subject: [PATCH 17/22] AUTOTOOLS: Fix warning AC_LANG_CONFTEST: no AC_LANG_SOURCE call detected in body Autoconf 2.68 requires that calling macros such as AC_PREPROC_IFELSE or AC_LINK_IFELSE requires the use of AC_LANG_SOURCE or AC_LANG_PROGRAM to generate the source code to compile. AC_LANG_PROGRAM was used but was not used properly: e.g. dnl Wrongly updated code (will still issue a warning) AC_LINK_IFELSE(AC_LANG_SOURCE([int main() { return 0; }]), [some=thing], [some=other]) dnl Correctly updated code AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 0; }])], [some=thing], [some=other]) Signed-off-by: Nalin Dahyabhai --- diff --git a/configure.ac b/configure.ac index 80234e3..a1d2324 100644 --- a/configure.ac +++ b/configure.ac @@ -193,7 +193,7 @@ if ! ${configure_dist_target_only:-false} ; then LIBS="$RESOLV_LIBS" AC_CHECK_HEADERS(resolv.h arpa/nameser.h) have_ns_initparse=false - AC_LINK_IFELSE(AC_LANG_PROGRAM([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ #ifdef HAVE_RESOLV_H #include #endif @@ -203,10 +203,10 @@ if ! ${configure_dist_target_only:-false} ; then ],[ ns_msg msg; ns_initparse(NULL, 0, &msg); - ]), + ])], have_ns_initparse=true, - LIBS="-lbind $LIBS" - AC_LINK_IFELSE(AC_LANG_PROGRAM([ + [LIBS="-lbind $LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([ #ifdef HAVE_RESOLV_H #include #endif @@ -216,12 +216,12 @@ if ! ${configure_dist_target_only:-false} ; then ],[ ns_msg msg; ns_initparse(NULL, 0, &msg); - ]), + ])], RESOLV_LIBS="-lbind $RESOLV_LIBS" have_ns_initparse=true, AC_MSG_WARN([cannot find ns_initparse() in libresolv or libbind]) have_ns_initparse=false - ) + )] ) AC_ARG_ENABLE(srv-location, AS_HELP_STRING([--disable-srv-location],[disable SRV location for servers]), @@ -492,10 +492,11 @@ if ! ${configure_dist_target_only:-false} ; then AC_CHECK_HEADERS(gmp.h) AC_CHECK_FUNC(mpz_set_str,, LIBS="-lgmp $LIBS" - AC_LINK_IFELSE(AC_LANG_PROGRAM([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ #include #include - ],[mpz_get_str(NULL,10,NULL);]),GMP_LIBS="$GMP_LIBS -lgmp")) + ],[mpz_get_str(NULL,10,NULL);])], + [GMP_LIBS="$GMP_LIBS -lgmp"])) AC_MSG_CHECKING([for GMP]) if test $ac_cv_header_gmp_h = yes ; then AC_MSG_RESULT(found) From 3341fe4ce146c47d6d2073592b8ca6894a079a4f Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Feb 23 2017 17:02:40 +0000 Subject: [PATCH 18/22] Replace RAND_pseudo_bytes() with RAND_bytes() Signed-off-by: Nalin Dahyabhai --- diff --git a/src/keygen-o.c b/src/keygen-o.c index 82b8e1f..676db8b 100644 --- a/src/keygen-o.c +++ b/src/keygen-o.c @@ -67,7 +67,7 @@ make_filename(const char *prefix, char **marker) char *ret; size_t l; - if (!RAND_pseudo_bytes(suffix, sizeof(suffix))) { + if (!RAND_bytes(suffix, sizeof(suffix))) { /* Try again sometime later. */ cm_log(1, "Error generating suffix.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); diff --git a/src/local.c b/src/local.c index c71bb04..8450c9b 100644 --- a/src/local.c +++ b/src/local.c @@ -504,7 +504,7 @@ main(int argc, const char **argv) /* we're good */ } else #endif - if (!RAND_pseudo_bytes(uuid, sizeof(uuid))) { + if (!RAND_bytes(uuid, sizeof(uuid))) { /* Try again sometime later. */ cm_log(1, "Error generating UUID.\n"); return CM_SUBMIT_STATUS_UNREACHABLE; diff --git a/src/scepgen-o.c b/src/scepgen-o.c index 6e318e5..56efc2c 100644 --- a/src/scepgen-o.c +++ b/src/scepgen-o.c @@ -397,7 +397,7 @@ cm_scepgen_o_cooked(struct cm_store_ca *ca, struct cm_store_entry *entry, cm_log(1, "PRNG not seeded for generating key.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (RAND_pseudo_bytes(nonce, nonce_length) == -1) { + if (RAND_bytes(nonce, nonce_length) == -1) { cm_log(1, "PRNG unable to generate nonce.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } diff --git a/src/srvloc.c b/src/srvloc.c index c80bebb..515fe0f 100644 --- a/src/srvloc.c +++ b/src/srvloc.c @@ -90,7 +90,7 @@ cm_srvloc_rand(unsigned int range) if (RAND_status() != 1) { return 0; } - if (RAND_pseudo_bytes((unsigned char *) &r, sizeof(r)) == -1) { + if (RAND_bytes((unsigned char *) &r, sizeof(r)) == -1) { return 0; } if (r < 0) { diff --git a/src/tdbus.c b/src/tdbus.c index 5f377f4..cb0a8ad 100644 --- a/src/tdbus.c +++ b/src/tdbus.c @@ -882,7 +882,7 @@ cm_tdbus_setup_private(struct tevent_context *ec, void *data, } else #endif #ifdef HAVE_OPENSSL - if (!RAND_pseudo_bytes(uuid, sizeof(uuid))) { + if (!RAND_bytes(uuid, sizeof(uuid))) { /* Try again sometime later. */ cm_log(1, "Error generating UUID.\n"); talloc_free(tdb); From d158a8521234d978a8ecfe12b2829cd6d0c7e8bb Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:40 +0000 Subject: [PATCH 19/22] Don't depend on i2d_X509_EXTENSIONS Don't depend on i2d_X509_EXTENSIONS(), which didn't exist on CentOS 5, to copy extensions from a request to a certificate. Instead, use logic from Tomas Mraz's patch to just iterate through them and call X509_add_req(). Signed-off-by: Nalin Dahyabhai --- diff --git a/src/submit-o.c b/src/submit-o.c index d44dc2d..45c7300 100644 --- a/src/submit-o.c +++ b/src/submit-o.c @@ -65,9 +65,10 @@ cm_submit_o_set_things(X509 **cert, X509 *signer, unsigned char uuid[16], unsign CERTCertificate subject, issuer; CERTSignedData scert; SECItem item, *encoded; + X509_EXTENSION *ext; unsigned char *p, *q; const unsigned char *d; - int length, l; + int length, l, i; arena = PORT_NewArena(sizeof(double)); if (arena == NULL) { @@ -110,6 +111,17 @@ cm_submit_o_set_things(X509 **cert, X509 *signer, unsigned char uuid[16], unsign free(p); } + for (i = 0; i < sk_X509_EXTENSION_num(extensions); i++) { + ext = sk_X509_EXTENSION_value(extensions, i); + if (ext != NULL) { + if (X509_add_ext(*cert, ext, -1) != 1) { + cm_log(1, "Error adding extension to certificate."); + PORT_FreeArena(arena, PR_TRUE); + return; + } + } + } + length = i2d_X509(*cert, NULL); if (length < 0) { cm_log(1, "Error encoding cert."); @@ -155,25 +167,6 @@ cm_submit_o_set_things(X509 **cert, X509 *signer, unsigned char uuid[16], unsign } } - length = i2d_X509_EXTENSIONS(extensions, NULL); - p = q = malloc(length); - l = i2d_X509_EXTENSIONS(extensions, &q); - if (l != length) { - cm_log(1, "Error encoding extensions: %d != %d.", l, length); - free(p); - PORT_FreeArena(arena, PR_TRUE); - return; - } - item.data = p; - item.len = length; - if (SEC_ASN1DecodeItem(arena, &subject.extensions, CERT_SequenceOfCertExtensionTemplate, &item) != SECSuccess) { - cm_log(1, "Error decoding extensions: %s.", PR_ErrorToName(PORT_GetError())); - free(p); - PORT_FreeArena(arena, PR_TRUE); - return; - } - free(p); - memset(&scert.data, 0, sizeof(scert.data)); encoded = SEC_ASN1EncodeItem(arena, &scert.data, &subject, CERT_CertificateTemplate); if (encoded != &scert.data) { @@ -265,6 +258,7 @@ cm_submit_o_sign(void *parent, char *csr, #endif /* Add a signature so that it looks right...ish. */ X509_sign(*cert, signer_key, cm_prefs_ossl_hash()); + /* Add extensions and possibly add deprecated UUIDs. */ cm_submit_o_set_things(cert, signer, uuid, uuid_len, X509_REQ_get_extensions(req)); /* add basic constraints if needed */ From 72fb38c431ee692f55c7dcad802bd4dd235b7b4d Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:40 +0000 Subject: [PATCH 20/22] Call X509_check_purpose before reading ex_kusage Call X509_check_purpose() before attempting to read back a certificate's key usage extension's value. From a patch by Lukas Slebodnik. Signed-off-by: Nalin Dahyabhai --- diff --git a/src/util-o.c b/src/util-o.c index dc515c6..0415014 100644 --- a/src/util-o.c +++ b/src/util-o.c @@ -420,6 +420,8 @@ util_X509_get_key_usage(X509 *x) #ifdef HAVE_X509_GET_KEY_USAGE return X509_get_key_usage(x); #else + /* Call for side-effect of computing hash and caching extensions */ + X509_check_purpose(x, -1, -1); return x->ex_kusage; #endif } From 70ac7ee8168c3f6ce0b5f3239deb233bd6989a4d Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:40 +0000 Subject: [PATCH 21/22] Avoid a variable reuse in get_ostring_attribute Avoid reusing the index variable for a length calculation in get_ostring_attribute. Tomas Mraz's rewrite of both functions carried the fix over from get_pstring_attribute, and added checks for NULL extension values and extensions with multiple values; incorporate most of those changes. Signed-off-by: Nalin Dahyabhai --- diff --git a/src/pkcs7.c b/src/pkcs7.c index 79af491..991ef91 100644 --- a/src/pkcs7.c +++ b/src/pkcs7.c @@ -798,22 +798,26 @@ get_pstring_attribute(void *parent, STACK_OF(X509_ATTRIBUTE) *attrs, int nid) } for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { a = sk_X509_ATTRIBUTE_value(attrs, i); + if (a == NULL) { /* should not happen */ + continue; + } if (OBJ_obj2nid(util_X509_ATTRIBUTE_get0_object(a)) != nid) { continue; } - if (X509_ATTRIBUTE_count(a) > 0) { - value = X509_ATTRIBUTE_get0_type(a, 0); - if (value->type == V_ASN1_PRINTABLESTRING) { - p = value->value.printablestring; - if (p != NULL) { - len = util_ASN1_STRING_length(p); - s = (const char *) util_ASN1_STRING_get0_data(p); - ret = talloc_size(parent, len + 1); - if (ret != NULL) { - memcpy(ret, s, len); - ret[len] = '\0'; - return ret; - } + if (X509_ATTRIBUTE_count(a) != 1) { + continue; + } + value = X509_ATTRIBUTE_get0_type(a, 0); + if ((value != NULL) && (value->type == V_ASN1_PRINTABLESTRING)) { + p = value->value.printablestring; + if (p != NULL) { + len = util_ASN1_STRING_length(p); + s = (const char *) util_ASN1_STRING_get0_data(p); + ret = talloc_size(parent, len + 1); + if (ret != NULL) { + memcpy(ret, s, len); + ret[len] = '\0'; + return ret; } } } @@ -829,7 +833,7 @@ get_ostring_attribute(void *parent, STACK_OF(X509_ATTRIBUTE) *attrs, int nid, ASN1_TYPE *value; ASN1_OCTET_STRING *p; const unsigned char *s; - int i; + int i, len; *ret = NULL; *length = 0; @@ -838,22 +842,26 @@ get_ostring_attribute(void *parent, STACK_OF(X509_ATTRIBUTE) *attrs, int nid, } for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { a = sk_X509_ATTRIBUTE_value(attrs, i); + if (a == NULL) { /* should not happen */ + continue; + } if (OBJ_obj2nid(util_X509_ATTRIBUTE_get0_object(a)) != nid) { continue; } - if (X509_ATTRIBUTE_count(a) > 0) { - value = X509_ATTRIBUTE_get0_type(a, 0); - if (value->type == V_ASN1_OCTET_STRING) { - p = value->value.octet_string; - if (p != NULL) { - i = util_ASN1_STRING_length(p); - s = util_ASN1_STRING_get0_data(p); - *ret = talloc_size(parent, i + 1); - if (*ret != NULL) { - memcpy(*ret, s, i); - *length = i; - return; - } + if (X509_ATTRIBUTE_count(a) != 1) { + continue; + } + value = X509_ATTRIBUTE_get0_type(a, 0); + if ((value != NULL) && (value->type == V_ASN1_OCTET_STRING)) { + p = value->value.octet_string; + if (p != NULL) { + len = util_ASN1_STRING_length(p); + s = util_ASN1_STRING_get0_data(p); + *ret = talloc_size(parent, len + 1); + if (*ret != NULL) { + memcpy(*ret, s, len); + *length = len; + return; } } } From 96c861fbad108e9dc3b7b02add01ab38ee2eb2c0 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Feb 23 2017 17:02:40 +0000 Subject: [PATCH 22/22] Go back to ensuring proper sorting of SCEP attribs Switch to Lukas Slebodnik's rewrite of cm_scepgen_n_resign(), which avoids a round trip through NSS's DER decoder and encoder. Signed-off-by: Nalin Dahyabhai --- diff --git a/src/scepgen-n.c b/src/scepgen-n.c index 8f3c160..d6735aa 100644 --- a/src/scepgen-n.c +++ b/src/scepgen-n.c @@ -72,53 +72,17 @@ struct cm_scepgen_state { struct cm_subproc_state *subproc; }; -/* Ad-hoc. */ -static const SEC_ASN1Template -cm_scepgen_n_certattr_template[] = { - { - .kind = SEC_ASN1_SEQUENCE, - .offset = 0, - .sub = NULL, - .size = sizeof(CERTAttribute), - }, - { - .kind = SEC_ASN1_OBJECT_ID, - .offset = offsetof(CERTAttribute, attrType), - .sub = NULL, - .size = sizeof(SECItem), - }, - { - .kind = SEC_ASN1_SET_OF, - .offset = offsetof(CERTAttribute, attrValue), - .sub = &SEC_AnyTemplate, - .size = 0, - }, - {0, 0, NULL, 0}, -}; - -static const SEC_ASN1Template -cm_scepgen_n_set_of_certattr_template[] = { - { - .kind = SEC_ASN1_SET_OF, - .offset = 0, - .sub = cm_scepgen_n_certattr_template, - .size = 0, - }, -}; - static void cm_scepgen_n_resign(PKCS7 *p7, SECKEYPrivateKey *privkey) { - PLArenaPool *arena; - SECItem signature, item; + unsigned char *sabuf = NULL, *u; + int salen, l; + SECItem signature; SECOidTag digalg, sigalg; PKCS7_SIGNER_INFO *sinfo; - X509_ATTRIBUTE *a; - CERTAttribute **attr, aitem; - unsigned char *p, *q; - int len, auth_attr_count, i, j, l; if (p7 == NULL) { + cm_log(1, "Nothing to resign.\n"); return; } if (sk_PKCS7_SIGNER_INFO_num(p7->d.sign->signer_info) != 1) { @@ -126,48 +90,21 @@ cm_scepgen_n_resign(PKCS7 *p7, SECKEYPrivateKey *privkey) _exit(CM_SUB_STATUS_INTERNAL_ERROR); } sinfo = sk_PKCS7_SIGNER_INFO_value(p7->d.sign->signer_info, 0); - - arena = PORT_NewArena(sizeof(double)); - if (arena == NULL) { - cm_log(1, "Out of memory re-signing data."); + salen = ASN1_item_i2d((ASN1_VALUE *)sinfo->auth_attr, NULL, &PKCS7_ATTR_SIGN_it); + u = sabuf = malloc(salen); + if (sabuf == NULL) { + cm_log(1, "Out of memory.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - - auth_attr_count = X509at_get_attr_count(sinfo->auth_attr); - attr = PORT_ArenaZAlloc(arena, (auth_attr_count + 1) * sizeof(CERTAttribute*)); - for (i = j = 0; i < auth_attr_count; i++) { - a = X509at_get_attr(sinfo->auth_attr, i); - len = i2d_X509_ATTRIBUTE(a, NULL); - if (len < 0) { - cm_log(1, "Error determining size of X509 attribute."); - _exit(CM_SUB_STATUS_INTERNAL_ERROR); - } - p = q = malloc(len); - l = i2d_X509_ATTRIBUTE(a, &q); - if (l != len) { - cm_log(1, "Error encoding X509 attribute."); - _exit(CM_SUB_STATUS_INTERNAL_ERROR); - } - memset(&item, 0, sizeof(item)); - item.data = p; - item.len = len; - memset(&aitem, 0, sizeof(aitem)); - if (SEC_ASN1DecodeItem(arena, &aitem, cm_scepgen_n_certattr_template, &item) == SECSuccess) { - attr[j] = PORT_ArenaZAlloc(arena, sizeof(CERTAttribute)); - if (attr[j] == NULL) { - cm_log(1, "Out of memory copying X509 attribute."); - _exit(CM_SUB_STATUS_INTERNAL_ERROR); - } - *(attr[j]) = aitem; - j++; - } - free(p); - } - memset(&item, 0, sizeof(item)); - if (SEC_ASN1EncodeItem(arena, &item, &attr, cm_scepgen_n_set_of_certattr_template) != &item) { - cm_log(1, "Unable to encode signing attributes.\n"); + /* ASN1_item_i2d doesn't actually modify the passed-in pointer, which + * allows it to allocate the memory on its own, but we want to handle + * that ourselves. */ + l = ASN1_item_i2d((ASN1_VALUE *)sinfo->auth_attr, &u, &PKCS7_ATTR_SIGN_it); + if (l != salen) { + cm_log(1, "Error encoding attributes.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } + memset(&signature, 0, sizeof(signature)); digalg = cm_submit_n_tag_from_nid(OBJ_obj2nid(sinfo->digest_alg->algorithm)); sigalg = SEC_GetSignatureAlgorithmOidTag(privkey->keyType, digalg); @@ -175,7 +112,7 @@ cm_scepgen_n_resign(PKCS7 *p7, SECKEYPrivateKey *privkey) cm_log(1, "Unable to match digest algorithm and key.\n"); _exit(CM_SUB_STATUS_INTERNAL_ERROR); } - if (SEC_SignData(&signature, item.data, item.len, privkey, + if (SEC_SignData(&signature, sabuf, salen, privkey, sigalg) != SECSuccess) { cm_log(1, "Error re-signing: %s.\n", PR_ErrorToName(PORT_GetError()));