diff options
author | Stef Walter <stefw@gnome.org> | 2013-03-14 10:05:17 +0100 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2013-03-15 17:19:01 +0100 |
commit | 86e60637394340ef2fa3b3db6b451dac1d73052b (patch) | |
tree | 8fa4f4c353534ffc259f9e333e64fbf7d068e913 | |
parent | bf63f009cd4a1147a3e0684d898f140f46666b0e (diff) |
trust: Rework input path treatment
* Accept a single --with-trust-paths argument to ./configure
which cotnains all the input paths.
* The --with-system-anchors and --with-system-certificates
./configure arguments are no longer supported. Since they were
only present briefly, no provision is made for backwards
compatibility.
* Each input file is treated as containing anchors by default
unless an input certificate contains detailed trust information.
* The files in each input directory are not automatically treated
as anchors unless a certificate contains detailed trust information.
* The files in anchors/ subdirectory of each input directory are
automatically marked as anchors.
* The files in the blacklist/ subdirectory of each input directory
are automatically marked as blacklisted.
* Update tests and move around test certificates so we can
test these changes.
https://bugs.freedesktop.org/show_bug.cgi?id=62327
-rw-r--r-- | build/certs/Makefile.am | 13 | ||||
-rw-r--r-- | build/certs/self-signed-with-ku.der | bin | 501 -> 478 bytes | |||
-rw-r--r-- | configure.ac | 74 | ||||
-rw-r--r-- | doc/manual/p11-kit-trust.xml | 61 | ||||
-rw-r--r-- | p11-kit/p11-kit-1.pc.in | 3 | ||||
-rw-r--r-- | trust/module.c | 21 | ||||
-rw-r--r-- | trust/parser.c | 47 | ||||
-rw-r--r-- | trust/tests/certificates/self-signed-with-ku.der | bin | 501 -> 0 bytes | |||
-rw-r--r-- | trust/tests/files/self-signed-with-eku.der (renamed from trust/tests/certificates/self-signed-with-eku.der) | bin | 480 -> 480 bytes | |||
-rw-r--r-- | trust/tests/frob-token.c | 2 | ||||
-rw-r--r-- | trust/tests/input/anchors/cacert3.der (renamed from trust/tests/anchors/cacert3.der) | bin | 1885 -> 1885 bytes | |||
-rw-r--r-- | trust/tests/input/anchors/testing-ca.der (renamed from trust/tests/anchors/testing-ca.der) | bin | 970 -> 970 bytes | |||
-rw-r--r-- | trust/tests/input/blacklist/self-server.der (renamed from trust/tests/files/self-server.der) | bin | 396 -> 396 bytes | |||
-rw-r--r-- | trust/tests/input/cacert-ca.der (renamed from trust/tests/certificates/cacert-ca.der) | bin | 1857 -> 1857 bytes | |||
-rw-r--r-- | trust/tests/input/distrusted.pem | 23 | ||||
-rw-r--r-- | trust/tests/test-module.c | 8 | ||||
-rw-r--r-- | trust/tests/test-session.c | 2 | ||||
-rw-r--r-- | trust/tests/test-token.c | 123 | ||||
-rw-r--r-- | trust/token.c | 78 | ||||
-rw-r--r-- | trust/token.h | 3 |
20 files changed, 318 insertions, 140 deletions
diff --git a/build/certs/Makefile.am b/build/certs/Makefile.am index 4428a2e..1d57935 100644 --- a/build/certs/Makefile.am +++ b/build/certs/Makefile.am @@ -7,7 +7,7 @@ TRUST = $(top_srcdir)/trust/tests TOOLS = $(top_srcdir)/tools/tests prepare-certs: - cp -v cacert3.der $(TRUST)/anchors + cp -v cacert3.der $(TRUST)/input/anchors cp -v cacert3.der $(TRUST)/files cp -v cacert3.der $(TOOLS)/files openssl x509 -in cacert3.der -inform DER -out $(TRUST)/files/cacert3.pem @@ -25,14 +25,15 @@ prepare-certs: -addreject ipsecUser -addreject timeStamping cat $(TOOLS)/files/cacert3-trusted-client-server-alias.pem \ $(TOOLS)/files/cacert3-trusted-alias.pem > $(TOOLS)/files/cacert3-trusted-multiple.pem - cp -v cacert-ca.der $(TRUST)/certificates + cp -v cacert-ca.der $(TRUST)/input cp -v cacert-ca.der $(TRUST)/files openssl x509 -in redhat-newca.der -inform DER -out $(TRUST)/files/distrusted.pem \ -addreject clientAuth -setalias "Red Hat Is the CA" - cp -v self-server.der $(TRUST)/files - cp -v self-signed-with-eku.der $(TRUST)/certificates - cp -v self-signed-with-ku.der $(TRUST)/certificates - cp -v testing-ca.der $(TRUST)/anchors + cp -v $(TRUST)/files/distrusted.pem $(TRUST)/input + cp -v self-server.der $(TRUST)/input/blacklist + cp -v self-signed-with-eku.der $(TRUST)/files + cp -v self-signed-with-ku.der $(TRUST)/files + cp -v testing-ca.der $(TRUST)/input/anchors cp -v testing-server.der $(TRUST)/files # Rebuild the self-signed certificates. This is almost never necessary and diff --git a/build/certs/self-signed-with-ku.der b/build/certs/self-signed-with-ku.der Binary files differindex e6f36e3..51bb227 100644 --- a/build/certs/self-signed-with-ku.der +++ b/build/certs/self-signed-with-ku.der diff --git a/configure.ac b/configure.ac index 66fcff9..63ba012 100644 --- a/configure.ac +++ b/configure.ac @@ -178,81 +178,51 @@ AS_IF([test "$enable_trust_module" != "no"], [enable_trust_module="yes"]) AM_CONDITIONAL(WITH_TRUST_MODULE, test "$enable_trust_module" = "yes") AC_MSG_RESULT([$enable_trust_module]) -AC_ARG_WITH([system-anchors], - AS_HELP_STRING([--with-system-anchors=@<:@path@:>@]: - [files or directories containing system CA anchors]) +AC_ARG_WITH([trust-paths], + AS_HELP_STRING([--with-trust-paths=@<:@path@:>@]: + [input paths for trust module]) ) -AC_MSG_CHECKING([location of system CA anchors]) +AC_MSG_CHECKING([for trust module paths]) # This option was disabled, no anchors -if test "$with_system_anchors" = "no"; then - with_system_anchors="" +if test "$with_trust_paths" = "no"; then + with_trust_paths="" AC_MSG_RESULT([disabled]) elif test "$enable_trust_module" != "yes"; then - if test "$with_system_anchors" != ""; then - AC_MSG_ERROR([need --enable-trust-module in order to use system anchors.]) + if test "$with_trust_paths" != ""; then + AC_MSG_ERROR([need --enable-trust-module in order to specify trust module paths.]) fi - with_system_anchors="" + with_trust_paths="" AC_MSG_RESULT([disabled]) # Option was not set, try to detect -elif test "$with_system_anchors" = "" -o "$with_system_anchors" = "yes"; then - with_system_anchors="" +elif test "$with_trust_paths" = "" -o "$with_trust_paths" = "yes"; then + with_trust_paths="" for f in /etc/pki/tls/certs/ca-bundle.crt \ /etc/ssl/certs/ca-certificates.crt \ /etc/ssl/ca-bundle.pem \ /etc/ssl/ca-bundle.crt; do if test -f "$f"; then - with_system_anchors="$f" + with_trust_paths="$f" break fi done - if test "$with_system_anchors" = ""; then - AC_MSG_ERROR([could not find. Use --with-system-anchors=path to set, or --without-system-anchors to disable]) + if test "$with_trust_paths" = ""; then + AC_MSG_ERROR([could not find. Use --with-trust-paths=/path to set, or --without-trust-paths to disable]) fi - AC_MSG_RESULT($with_system_anchors) + AC_MSG_RESULT($with_trust_paths) else # Anchors explicitly set - AC_MSG_RESULT($with_system_anchors) + AC_MSG_RESULT($with_trust_paths) fi -AC_DEFINE_UNQUOTED(SYSTEM_ANCHORS, ["$with_system_anchors"], [The system anchor paths]) -AC_SUBST(with_system_anchors) - -AC_ARG_WITH([system-certificates], - AS_HELP_STRING([--with-system-certificates=@<:@path@:>@]: - [files or directories containing additional system certificates]) -) - -AC_MSG_CHECKING([location of additional system certificates]) - -# This option was disabled, no additional certificates -if test "$with_system_certificates" = "no"; then - with_system_certificates="" - AC_MSG_RESULT([disabled]) - -elif test "$enable_trust_module" != "yes"; then - if test "$with_system_certificates" != ""; then - AC_MSG_ERROR([need --enable-trust-module in order to use additional system certificates.]) - fi - with_system_certificates="" - AC_MSG_RESULT([disabled]) - -elif test "$with_system_certificates" = "yes"; then - AC_MSG_ERROR([--with-system-certificates requires paths as an argument]) - -else - # Anchors explicitly set - AC_MSG_RESULT($with_system_certificates) -fi - -AC_DEFINE_UNQUOTED(SYSTEM_CERTIFICATES, ["$with_system_certificates"], [Additional system certificate paths]) -AC_SUBST(with_system_certificates) +AC_DEFINE_UNQUOTED(TRUST_PATHS, ["$with_trust_paths"], [The trust module input paths]) +AC_SUBST(with_trust_paths) # -------------------------------------------------------------------- # GTK Doc @@ -453,6 +423,10 @@ AC_CONFIG_FILES([Makefile ]) AC_OUTPUT +# Format paths arguments which should wrap correctly in the output +indent='\n ' +trust_status=$(echo "$with_trust_paths" | sed -e "s/:/$indent/g") + AC_MSG_NOTICE([build options: Host: $host @@ -469,6 +443,6 @@ AC_MSG_NOTICE([build options: With libtasn1 dependency: $with_libtasn1 Build trust module: $enable_trust_module - System certificate anchor paths: $with_system_anchors - Other system certificate paths: $with_system_certificates + Trust module paths: $trust_status + ]) diff --git a/doc/manual/p11-kit-trust.xml b/doc/manual/p11-kit-trust.xml index 0e06446..06f168e 100644 --- a/doc/manual/p11-kit-trust.xml +++ b/doc/manual/p11-kit-trust.xml @@ -9,35 +9,16 @@ information is exposed as PKCS#11 objects.</para> <section id="trust-files"> - <title>Files loaded by the Module</title> + <title>Paths loaded by the Module</title> <para>The trust module loads certificates and trust policy information - from preconfigured directories and allows them to be looked up via - PKCS#11. The directories can be determined with using the following - commands:</para> + from preconfigured paths and allows them to be looked up via PKCS#11. + The input paths can be determined with using the following command:</para> - <itemizedlist> - <listitem> - <para>System Anchors: certificates in these locations - are automatically treated as certificate authority anchors - unless they contain information that prevents that. To check - which locations are being used, run the following command:</para> -<programlisting> -$ pkg-config --variable p11_system_anchors p11-kit-1 -/etc/pki/tls/certs/ca-bundle.trust.crt:/etc/pki/tls/anchors -</programlisting> - </listitem> - <listitem> - <para>System Certificates: certificates in these locations - are not treated as anchors, but simply made available through - the module. To find out which directory is used, run the - following command:</para> <programlisting> -$ pkg-config --variable p11_system_certificates p11-kit-1 -/etc/pki/tls/other-certs +$ pkg-config --variable p11_trust_paths p11-kit-1 +/usr/share/p11-kit/trust:/etc/pki/trust </programlisting> - </listitem> - </itemizedlist> <para>Files in the following formats are supported for loading by the trust policy module:</para> @@ -45,17 +26,43 @@ $ pkg-config --variable p11_system_certificates p11-kit-1 <variablelist> <varlistentry> <term>X.509 certificates</term> - <listitem><para>X.509 certificates in raw DER format.</para></listitem> + <listitem><para>X.509 certificates in raw DER format. Does not + automatically contain trust policy information.</para></listitem> + </varlistentry> + <varlistentry> + <term>PEM certificates</term> + <listitem><para>X.509 certificates in PEM format. These have a + <literal>BEGIN CERTIFICATE</literal> header. This file does not + automatically contain trust policy information.</para></listitem> </varlistentry> <varlistentry> <term>OpenSSL trust certificates</term> <listitem><para>OpenSSL specific certificates in PEM format that contain trust information. These have a - <literal>TRUSTED CERTIFICATE</literal> PEM header. Both - trust policy and blacklist information can be loaded + <literal>BEGIN TRUSTED CERTIFICATE</literal> PEM header. Both + trust anchor and blacklist information can be loaded from these files.</para></listitem> </varlistentry> </variablelist> + + <para>If the input path is a file, then it is loaded. Certificate(s) in the + file are automatically treated as anchors, unless they contain alternate + trust policy information.</para> + + <para>If the input path is a directory, files inside that directory are + parsed and loaded. If the file contains trust policy information (such as the + OpenSSL trust certificates) then it will be respected. Files without trust policy + information are not automatically marked as an anchor or blacklisted.</para> + + <para>In addition two optional subdirectories of the input path are loaded. Files + placed in the <literal>anchors/</literal> subdirectory become trust anchors + when they do not contain trust policy information. Files placed in the + <literal>blacklist/</literal> subdirectory are blacklisted whether they + contain trust information or not.</para> + + <para>The first input path becomes the first PKCS#11 token of the trust + module, and has the highest priority when callers search for trust + policy information.</para> </section> <section id="trust-nss"> diff --git a/p11-kit/p11-kit-1.pc.in b/p11-kit/p11-kit-1.pc.in index 441904d..d0d378d 100644 --- a/p11-kit/p11-kit-1.pc.in +++ b/p11-kit/p11-kit-1.pc.in @@ -10,9 +10,6 @@ p11_module_configs=@p11_package_config_modules@ p11_module_path=@p11_module_path@ proxy_module=@libdir@/p11-kit-proxy.so -p11_system_anchors=@with_system_anchors@ -p11_system_certificates=@with_system_certificates@ - # This is for compatibility. Other packages were using this to determine # the directory they should install their module configs to, so override # this and redirect them to the new location diff --git a/trust/module.c b/trust/module.c index bf9c0db..5ac018e 100644 --- a/trust/module.c +++ b/trust/module.c @@ -64,8 +64,7 @@ static struct _Shared { p11_dict *sessions; p11_token *token; - char *anchor_paths; - char *certificate_paths; + char *paths; } gl = { NULL, NULL }; /* Used during FindObjects */ @@ -115,13 +114,9 @@ parse_argument (char *arg) else *(value++) = 0; - if (strcmp (arg, "anchors") == 0) { - free (gl.anchor_paths); - gl.anchor_paths = value ? strdup (value) : NULL; - - } else if (strcmp (arg, "certificates") == 0) { - free (gl.certificate_paths); - gl.certificate_paths = value ? strdup (value) : NULL; + if (strcmp (arg, "paths") == 0) { + free (gl.paths); + gl.paths = value ? strdup (value) : NULL; } else { p11_message ("unrecognized module argument: %s", arg); @@ -219,9 +214,8 @@ sys_C_Finalize (CK_VOID_PTR reserved) rv = CKR_CRYPTOKI_NOT_INITIALIZED; } else { - free (gl.certificate_paths); - free (gl.anchor_paths); - gl.certificate_paths = gl.anchor_paths = NULL; + free (gl.paths); + gl.paths = NULL; p11_dict_free (gl.sessions); gl.sessions = NULL; @@ -290,8 +284,7 @@ sys_C_Initialize (CK_VOID_PTR init_args) p11_dict_ulongptr_equal, NULL, p11_session_free); - gl.token = p11_token_new (gl.anchor_paths ? gl.anchor_paths : SYSTEM_ANCHORS, - gl.certificate_paths ? gl.certificate_paths : SYSTEM_CERTIFICATES); + gl.token = p11_token_new (gl.paths ? gl.paths : TRUST_PATHS); if (gl.sessions == NULL || gl.token == NULL) { warn_if_reached (); diff --git a/trust/parser.c b/trust/parser.c index 3448f40..0b62f01 100644 --- a/trust/parser.c +++ b/trust/parser.c @@ -283,8 +283,8 @@ build_x509_certificate (p11_parser *parser, /* Filled in later */ CK_ULONG vcategory = 0; - CK_BBOOL vtrusted = CK_FALSE; - CK_BBOOL vdistrusted = CK_FALSE; + CK_BBOOL vtrusted = (parser->flags & P11_PARSE_FLAG_ANCHOR) ? CK_TRUE : CK_FALSE; + CK_BBOOL vdistrusted = (parser->flags & P11_PARSE_FLAG_BLACKLIST) ? CK_TRUE : CK_FALSE; CK_ATTRIBUTE certificate_type = { CKA_CERTIFICATE_TYPE, &vx509, sizeof (vx509) }; CK_ATTRIBUTE certificate_category = { CKA_CERTIFICATE_CATEGORY, &vcategory, sizeof (vcategory) }; @@ -780,6 +780,9 @@ build_openssl_extensions (p11_parser *parser, p11_dict *trust = NULL; p11_dict *reject = NULL; p11_dictiter iter; + CK_ATTRIBUTE *attr; + CK_BBOOL trusted; + CK_BBOOL distrust; void *key; int start; int end; @@ -832,6 +835,46 @@ build_openssl_extensions (p11_parser *parser, return_val_if_fail (ret == P11_PARSE_SUCCESS, ret); } + /* + * If loading from an blacklist flagged directory, then override all + * trust assumptionsinformation and mark this as a blacklisted certificate + */ + + if (parser->flags & P11_PARSE_FLAG_BLACKLIST) { + trusted = CK_FALSE; + distrust = CK_TRUE; + + /* + * OpenSSL model blacklists as anchors with all purposes being removed/rejected, + * we account for that here. If there is an ExtendedKeyUsage without any + * useful purposes, then treat like a blacklist. + */ + } else if (trust && p11_dict_size (trust) == 0) { + trusted = CK_FALSE; + distrust = CK_TRUE; + + /* + * Otherwise a 'TRUSTED CERTIFICATE' in an input directory is enough to + * mark this as a trusted certificate, even if we're not explicitly + * parsing an directory with the anchors flag. + */ + } else { + trusted = CK_TRUE; + distrust = CK_FALSE; + } + + attr = p11_attrs_find (cert, CKA_TRUSTED); + assert (attr != NULL); + assert (attr->pValue != NULL); + assert (attr->ulValueLen == sizeof (CK_BBOOL)); + *((CK_BBOOL *)attr->pValue) = trusted; + + attr = p11_attrs_find (cert, CKA_X_DISTRUSTED); + assert (attr != NULL); + assert (attr->pValue != NULL); + assert (attr->ulValueLen == sizeof (CK_BBOOL)); + *((CK_BBOOL *)attr->pValue) = distrust; + p11_dict_free (trust); p11_dict_free (reject); diff --git a/trust/tests/certificates/self-signed-with-ku.der b/trust/tests/certificates/self-signed-with-ku.der Binary files differdeleted file mode 100644 index e6f36e3..0000000 --- a/trust/tests/certificates/self-signed-with-ku.der +++ /dev/null diff --git a/trust/tests/certificates/self-signed-with-eku.der b/trust/tests/files/self-signed-with-eku.der Binary files differindex 33e0760..33e0760 100644 --- a/trust/tests/certificates/self-signed-with-eku.der +++ b/trust/tests/files/self-signed-with-eku.der diff --git a/trust/tests/frob-token.c b/trust/tests/frob-token.c index 95c129a..23856cf 100644 --- a/trust/tests/frob-token.c +++ b/trust/tests/frob-token.c @@ -52,7 +52,7 @@ main (int argc, return 2; } - token = p11_token_new (argv[1], NULL); + token = p11_token_new (argv[1]); count = p11_token_load (token); printf ("%d files loaded\n", count); diff --git a/trust/tests/anchors/cacert3.der b/trust/tests/input/anchors/cacert3.der Binary files differindex 56f8c88..56f8c88 100644 --- a/trust/tests/anchors/cacert3.der +++ b/trust/tests/input/anchors/cacert3.der diff --git a/trust/tests/anchors/testing-ca.der b/trust/tests/input/anchors/testing-ca.der Binary files differindex d3f70ea..d3f70ea 100644 --- a/trust/tests/anchors/testing-ca.der +++ b/trust/tests/input/anchors/testing-ca.der diff --git a/trust/tests/files/self-server.der b/trust/tests/input/blacklist/self-server.der Binary files differindex 68fe9af..68fe9af 100644 --- a/trust/tests/files/self-server.der +++ b/trust/tests/input/blacklist/self-server.der diff --git a/trust/tests/certificates/cacert-ca.der b/trust/tests/input/cacert-ca.der Binary files differindex 719b0ff..719b0ff 100644 --- a/trust/tests/certificates/cacert-ca.der +++ b/trust/tests/input/cacert-ca.der diff --git a/trust/tests/input/distrusted.pem b/trust/tests/input/distrusted.pem new file mode 100644 index 0000000..8de6ff0 --- /dev/null +++ b/trust/tests/input/distrusted.pem @@ -0,0 +1,23 @@ +-----BEGIN TRUSTED CERTIFICATE----- +MIIDsDCCAxmgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCVVMx +FzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRAwDgYDVQQHEwdSYWxlaWdoMRYwFAYD +VQQKEw1SZWQgSGF0LCBJbmMuMQswCQYDVQQLEwJJUzEWMBQGA1UEAxMNUmVkIEhh +dCBJUyBDQTEmMCQGCSqGSIb3DQEJARYXc3lzYWRtaW4tcmR1QHJlZGhhdC5jb20w +HhcNMDkwOTE2MTg0NTI1WhcNMTkwOTE0MTg0NTI1WjCBnTELMAkGA1UEBhMCVVMx +FzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRAwDgYDVQQHEwdSYWxlaWdoMRYwFAYD +VQQKEw1SZWQgSGF0LCBJbmMuMQswCQYDVQQLEwJJUzEWMBQGA1UEAxMNUmVkIEhh +dCBJUyBDQTEmMCQGCSqGSIb3DQEJARYXc3lzYWRtaW4tcmR1QHJlZGhhdC5jb20w +gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAN/HDWGiL8BarUWDIjNC6uxCXqYN +QkwcmhILX+cl+YuDDArFL1pYVrith228gF3dSUU5X7kIOmPkkjNheRkbnas61X+n +i3+KWvbX3q+h5VMxKX2cA1U+R3jLuXqYjF+N2gkPyPvxeoDuEncKAItw+mK/r+4L +WBb5nFzek7hP3017AgMBAAGjgf0wgfowHQYDVR0OBBYEFA2sGXDtBKdeeKv+i6g0 +6yEmwVY1MIHKBgNVHSMEgcIwgb+AFA2sGXDtBKdeeKv+i6g06yEmwVY1oYGjpIGg +MIGdMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExEDAOBgNV +BAcTB1JhbGVpZ2gxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xCzAJBgNVBAsTAklT +MRYwFAYDVQQDEw1SZWQgSGF0IElTIENBMSYwJAYJKoZIhvcNAQkBFhdzeXNhZG1p +bi1yZHVAcmVkaGF0LmNvbYIBATAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA +A4GBAFBgO5y3JcPXH/goumNBW7rr8m9EFZmQyK5gT1Ljv5qaCSZwxkAomhriv04p +mb1y8yjrK5OY3WwgaRaAWRHp4/hn2HWaRvx3S+gwLM7p8V1pWnbSFJOXF3kbuC41 +voMIMqAFfHKidKN/yrjJg/1ahIjSt11lMUvRJ4TNT+pk5VnBMB+gCgYIKwYBBQUH +AwIMEVJlZCBIYXQgSXMgdGhlIENB +-----END TRUSTED CERTIFICATE----- diff --git a/trust/tests/test-module.c b/trust/tests/test-module.c index 2d0e488..52fbe03 100644 --- a/trust/tests/test-module.c +++ b/trust/tests/test-module.c @@ -59,8 +59,7 @@ static void setup (CuTest *cu) { CK_C_INITIALIZE_ARGS args; - const char *anchors; - const char *certs; + const char *paths; char *arguments; CK_ULONG count; CK_RV rv; @@ -72,9 +71,8 @@ setup (CuTest *cu) CuAssertTrue (cu, rv == CKR_OK); memset (&args, 0, sizeof (args)); - anchors = SRCDIR "/anchors:" SRCDIR "/files/cacert-ca.der"; - certs = SRCDIR "/certificates"; - if (asprintf (&arguments, "anchors='%s' certificates='%s'", anchors, certs) < 0) + paths = SRCDIR "/input:" SRCDIR "/files/cacert-ca.der"; + if (asprintf (&arguments, "paths='%s'", paths) < 0) CuAssertTrue (cu, false && "not reached"); args.pReserved = arguments; args.flags = CKF_OS_LOCKING_OK; diff --git a/trust/tests/test-session.c b/trust/tests/test-session.c index d420d5c..e9031f2 100644 --- a/trust/tests/test-session.c +++ b/trust/tests/test-session.c @@ -53,7 +53,7 @@ struct { static void setup (CuTest *cu) { - test.token = p11_token_new ("", ""); + test.token = p11_token_new (""); CuAssertPtrNotNull (cu, test.token); test.session = p11_session_new (test.token); diff --git a/trust/tests/test-token.c b/trust/tests/test-token.c index 382d021..c566406 100644 --- a/trust/tests/test-token.c +++ b/trust/tests/test-token.c @@ -41,7 +41,9 @@ #include "attrs.h" #include "debug.h" +#include "pkcs11x.h" #include "library.h" +#include "test-data.h" #include "token.h" struct { @@ -51,8 +53,7 @@ struct { static void setup (CuTest *cu) { - test.token = p11_token_new (SRCDIR "/anchors:" SRCDIR "/files/cacert-ca.der", - SRCDIR "/files/self-server.der"); + test.token = p11_token_new (SRCDIR "/input:" SRCDIR "/files/self-server.der:" SRCDIR "/files/cacert-ca.der"); CuAssertPtrNotNull (cu, test.token); } @@ -72,7 +73,7 @@ test_token_load (CuTest *cu) setup (cu); count = p11_token_load (test.token); - CuAssertIntEquals (cu, 5, count); + CuAssertIntEquals (cu, 7, count); /* A certificate and trust object for each parsed object + builtin */ objects = p11_token_objects (test.token); @@ -81,6 +82,121 @@ test_token_load (CuTest *cu) teardown (cu); } +static bool +check_object (CK_ATTRIBUTE *match) +{ + CK_ATTRIBUTE *attrs; + p11_dict *objects; + p11_dictiter iter; + + objects = p11_token_objects (test.token); + + p11_dict_iterate (objects, &iter); + while (p11_dict_next (&iter, NULL, (void **)&attrs)) { + if (p11_attrs_match (attrs, match)) + return true; + } + + return false; +} + +static void +test_token_flags (CuTest *cu) +{ + CK_BBOOL falsev = CK_FALSE; + CK_BBOOL truev = CK_TRUE; + + /* + * blacklist comes from the input/distrust.pem file. It is not in the blacklist + * directory, but is an OpenSSL trusted certificate file, and is marked + * in the blacklist style for OpenSSL. + */ + + CK_ATTRIBUTE blacklist[] = { + { CKA_LABEL, "Red Hat Is the CA", 17 }, + { CKA_SERIAL_NUMBER, "\x02\x01\x01", 3 }, + { CKA_TRUSTED, &falsev, sizeof (falsev) }, + { CKA_X_DISTRUSTED, &truev, sizeof (truev) }, + { CKA_INVALID }, + }; + + /* + * blacklist2 comes from the input/blacklist/self-server.der file. It is + * explicitly put on the blacklist, even though it containts no trust + * policy information. + */ + + const unsigned char self_server_subject[] = { + 0x30, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, + 0x01, 0x19, 0x16, 0x03, 0x43, 0x4f, 0x4d, 0x31, 0x17, 0x30, 0x15, 0x06, 0x0a, 0x09, 0x92, 0x26, + 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x07, 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c, 0x45, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + }; + + CK_ATTRIBUTE blacklist2[] = { + { CKA_SUBJECT, (void *)self_server_subject, sizeof (self_server_subject) }, + { CKA_TRUSTED, &falsev, sizeof (falsev) }, + { CKA_X_DISTRUSTED, &truev, sizeof (truev) }, + { CKA_INVALID }, + }; + + /* + * anchor comes from the input/anchors/cacert3.der file. It is + * explicitly marked as an anchor, even though it containts no trust + * policy information. + */ + + CK_ATTRIBUTE anchor[] = { + { CKA_SUBJECT, (void *)test_cacert3_ca_subject, sizeof (test_cacert3_ca_subject) }, + { CKA_TRUSTED, &truev, sizeof (truev) }, + { CKA_X_DISTRUSTED, &falsev, sizeof (falsev) }, + { CKA_INVALID }, + }; + + const unsigned char cacert_root_subject[] = { + 0x30, 0x79, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x52, 0x6f, 0x6f, + 0x74, 0x20, 0x43, 0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, + 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, + 0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x40, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x6f, 0x72, 0x67, + }; + + /* + * notrust comes from the input/cacert-ca.der file. It contains no + * trust information, and is not explicitly marked as an anchor, so + * it's neither trusted or distrusted. + */ + + CK_ATTRIBUTE notrust[] = { + { CKA_SUBJECT, (void *)cacert_root_subject, sizeof (cacert_root_subject) }, + { CKA_TRUSTED, &falsev, sizeof (falsev) }, + { CKA_X_DISTRUSTED, &falsev, sizeof (falsev) }, + { CKA_INVALID }, + }; + + CK_ATTRIBUTE invalid[] = { + { CKA_LABEL, "Waonec9aoe9", 8 }, + { CKA_INVALID }, + }; + + setup (cu); + + if (p11_token_load (test.token) < 0) + CuFail (cu, "should not be reached"); + + CuAssertTrue (cu, !check_object (invalid)); + CuAssertTrue (cu, check_object (anchor)); + CuAssertTrue (cu, check_object (blacklist)); + CuAssertTrue (cu, check_object (blacklist2)); + CuAssertTrue (cu, check_object (notrust)); + + teardown (cu); +} + int main (void) { @@ -94,6 +210,7 @@ main (void) p11_message_quiet (); SUITE_ADD_TEST (suite, test_token_load); + SUITE_ADD_TEST (suite, test_token_flags); CuSuiteRun (suite); CuSuiteSummary (suite, output); diff --git a/trust/token.c b/trust/token.c index 3c0de4c..f96d865 100644 --- a/trust/token.c +++ b/trust/token.c @@ -50,6 +50,7 @@ #include <sys/types.h> #include <dirent.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -58,9 +59,7 @@ struct _p11_token { p11_parser *parser; p11_dict *objects; - const char *anchor_paths; - const char *other_paths; - const char *certificate_paths; + const char *paths; int loaded; }; @@ -149,11 +148,32 @@ loader_load_directory (p11_token *token, } static int +loader_load_subdirectory (p11_token *token, + const char *directory, + const char *subdir, + int flags) +{ + struct stat sb; + char *path; + int ret = 0; + + if (asprintf (&path, "%s/%s", directory, subdir) < 0) + return_val_if_reached (-1); + + if (stat (path, &sb) >= 0 && S_ISDIR (sb.st_mode)) + ret = loader_load_directory (token, path, flags); + + free (path); + return ret; +} + +static int loader_load_path (p11_token *token, - const char *path, - int flags) + const char *path) { struct stat sb; + int total; + int ret; if (stat (path, &sb) < 0) { if (errno == ENOENT) { @@ -167,16 +187,30 @@ loader_load_path (p11_token *token, return 0; } - if (S_ISDIR (sb.st_mode)) - return loader_load_directory (token, path, flags); - else - return loader_load_file (token, path, &sb, flags); + if (S_ISDIR (sb.st_mode)) { + total = 0; + + ret = loader_load_subdirectory (token, path, "anchors", P11_PARSE_FLAG_ANCHOR); + return_val_if_fail (ret >= 0, ret); + total += ret; + + ret = loader_load_subdirectory (token, path, "blacklist", P11_PARSE_FLAG_BLACKLIST); + return_val_if_fail (ret >= 0, ret); + total += ret; + + ret = loader_load_directory (token, path, P11_PARSE_FLAG_NONE); + return_val_if_fail (ret >= 0, ret); + total += ret; + + return total; + } else { + return loader_load_file (token, path, &sb, P11_PARSE_FLAG_ANCHOR); + } } static int loader_load_paths (p11_token *token, - const char *paths, - int flags) + const char *paths) { const char *pos; int total = 0; @@ -199,7 +233,7 @@ loader_load_paths (p11_token *token, if (path[0] != '\0') { /* We don't expect this to fail except for in strange circumstances */ - ret = loader_load_path (token, path, flags); + ret = loader_load_path (token, path); if (ret < 0) return_val_if_reached (-1); total += ret; @@ -383,8 +417,7 @@ int p11_token_load (p11_token *token) { int builtins; - int anchors; - int other; + int count; if (token->loaded) return 0; @@ -392,15 +425,10 @@ p11_token_load (p11_token *token) builtins = load_builtin_objects (token); - anchors = loader_load_paths (token, token->anchor_paths, P11_PARSE_FLAG_ANCHOR); - if (anchors < 0) - return anchors; - - other = loader_load_paths (token, token->other_paths, P11_PARSE_FLAG_NONE); - if (other < 0) - return other; + count = loader_load_paths (token, token->paths); + return_val_if_fail (count >= 0, count); - return anchors + builtins + other; + return count + builtins; } p11_dict * @@ -421,8 +449,7 @@ p11_token_free (p11_token *token) } p11_token * -p11_token_new (const char *anchor_paths, - const char *other_paths) +p11_token_new (const char *paths) { p11_token *token; @@ -437,8 +464,7 @@ p11_token_new (const char *anchor_paths, free, p11_attrs_free); return_val_if_fail (token->objects != NULL, NULL); - token->anchor_paths = anchor_paths; - token->other_paths = other_paths; + token->paths = paths; token->loaded = 0; return token; diff --git a/trust/token.h b/trust/token.h index 1152a68..0c53d32 100644 --- a/trust/token.h +++ b/trust/token.h @@ -39,8 +39,7 @@ typedef struct _p11_token p11_token; -p11_token * p11_token_new (const char *anchor_paths, - const char *other_paths); +p11_token * p11_token_new (const char *paths); void p11_token_free (p11_token *token); |