diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:33:12 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:33:12 +0000 |
commit | 36082a2fe36ecd800d784ae44c14f1f18c66a7e9 (patch) | |
tree | 6c68e0c0097987aff85a01dabddd34b862309a7c /tests/pkcs12_encode.c | |
parent | Initial commit. (diff) | |
download | gnutls28-36082a2fe36ecd800d784ae44c14f1f18c66a7e9.tar.xz gnutls28-36082a2fe36ecd800d784ae44c14f1f18c66a7e9.zip |
Adding upstream version 3.7.9.upstream/3.7.9upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/pkcs12_encode.c')
-rw-r--r-- | tests/pkcs12_encode.c | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/tests/pkcs12_encode.c b/tests/pkcs12_encode.c new file mode 100644 index 0000000..ea39f3d --- /dev/null +++ b/tests/pkcs12_encode.c @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2009-2012 Free Software Foundation, Inc. + * + * Author: Simon Josefsson + * + * This file is part of GnuTLS. + * + * GnuTLS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GnuTLS; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gnutls/gnutls.h> +#include <gnutls/x509.h> +#include <gnutls/pkcs12.h> + +#include "utils.h" + +#include <stdio.h> +#include <stdlib.h> + +static char client_pem[] = + "-----BEGIN CERTIFICATE-----\n" + "MIICHjCCAYmgAwIBAgIERiYdNzALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n" + "VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTI3WhcNMDgwNDE3MTMyOTI3WjAdMRsw\n" + "GQYDVQQDExJHbnVUTFMgdGVzdCBjbGllbnQwgZwwCwYJKoZIhvcNAQEBA4GMADCB\n" + "iAKBgLtmQ/Xyxde2jMzF3/WIO7HJS2oOoa0gUEAIgKFPXKPQ+GzP5jz37AR2ExeL\n" + "ZIkiW8DdU3w77XwEu4C5KL6Om8aOoKUSy/VXHqLnu7czSZ/ju0quak1o/8kR4jKN\n" + "zj2AC41179gAgY8oBAOgIo1hBAf6tjd9IQdJ0glhaZiQo1ipAgMBAAGjdjB0MAwG\n" + "A1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDwYDVR0PAQH/BAUDAweg\n" + "ADAdBgNVHQ4EFgQUTLkKm/odNON+3svSBxX+odrLaJEwHwYDVR0jBBgwFoAU6Twc\n" + "+62SbuYGpFYsouHAUyfI8pUwCwYJKoZIhvcNAQEFA4GBALujmBJVZnvaTXr9cFRJ\n" + "jpfc/3X7sLUsMvumcDE01ls/cG5mIatmiyEU9qI3jbgUf82z23ON/acwJf875D3/\n" + "U7jyOsBJ44SEQITbin2yUeJMIm1tievvdNXBDfW95AM507ShzP12sfiJkJfjjdhy\n" + "dc8Siq5JojruiMizAf0pA7in\n" "-----END CERTIFICATE-----\n"; +const gnutls_datum_t client_dat = + { (void *) client_pem, sizeof(client_pem) }; + +static char ca_pem[] = + "-----BEGIN CERTIFICATE-----\n" + "MIIB5zCCAVKgAwIBAgIERiYdJzALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n" + "VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTExWhcNMDgwNDE3MTMyOTExWjAZMRcw\n" + "FQYDVQQDEw5HbnVUTFMgdGVzdCBDQTCBnDALBgkqhkiG9w0BAQEDgYwAMIGIAoGA\n" + "vuyYeh1vfmslnuggeEKgZAVmQ5ltSdUY7H25WGSygKMUYZ0KT74v8C780qtcNt9T\n" + "7EPH/N6RvB4BprdssgcQLsthR3XKA84jbjjxNCcaGs33lvOz8A1nf8p3hD+cKfRi\n" + "kfYSW2JazLrtCC4yRCas/SPOUxu78of+3HiTfFm/oXUCAwEAAaNDMEEwDwYDVR0T\n" + "AQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwQAMB0GA1UdDgQWBBTpPBz7rZJu5gak\n" + "Viyi4cBTJ8jylTALBgkqhkiG9w0BAQUDgYEAiaIRqGfp1jPpNeVhABK60SU0KIAy\n" + "njuu7kHq5peUgYn8Jd9zNzExBOEp1VOipGsf6G66oQAhDFp2o8zkz7ZH71zR4HEW\n" + "KoX6n5Emn6DvcEH/9pAhnGxNHJAoS7czTKv/JDZJhkqHxyrE1fuLsg5Qv25DTw7+\n" + "PfqUpIhz5Bbm7J4=\n" "-----END CERTIFICATE-----\n"; +const gnutls_datum_t ca_dat = { (void *) ca_pem, sizeof(ca_pem) }; + +static void tls_log_func(int level, const char *str) +{ + fprintf(stderr, "|<%d>| %s", level, str); +} + +#define FIPS_PUSH_CONTEXT() do { \ + if (gnutls_fips140_mode_enabled()) { \ + ret = gnutls_fips140_push_context(fips_context); \ + if (ret < 0) { \ + fail("gnutls_fips140_push_context failed\n"); \ + } \ + } \ +} while (0) + +#define FIPS_POP_CONTEXT(state) do { \ + if (gnutls_fips140_mode_enabled()) { \ + ret = gnutls_fips140_pop_context(); \ + if (ret < 0) { \ + fail("gnutls_fips140_context_pop failed\n"); \ + } \ + fips_state = gnutls_fips140_get_operation_state(fips_context); \ + if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \ + fail("operation state is not " # state " (%d)\n", \ + fips_state); \ + } \ + } \ +} while (0) + +void doit(void) +{ + gnutls_pkcs12_t pkcs12; + gnutls_x509_crt_t client; + gnutls_x509_crt_t ca; + gnutls_pkcs12_bag_t bag; + unsigned char key_id_buf[20]; + gnutls_datum_t key_id; + int ret, indx; + char outbuf[10240]; + size_t size; + unsigned i; + gnutls_fips140_context_t fips_context; + gnutls_fips140_operation_state_t fips_state; + size_t n_tests = 0; + struct tests { + const char *name; + gnutls_x509_crt_t crt; + const char *friendly_name; + unsigned bag_encrypt_flags; + int bag_encrypt_expected; + } tests[2]; + + if (gnutls_fips140_mode_enabled()) + exit(77); + + ret = global_init(); + if (ret < 0) { + fprintf(stderr, "global_init %d", ret); + exit(1); + } + + gnutls_global_set_log_function(tls_log_func); + if (debug) + gnutls_global_set_log_level(4711); + + ret = gnutls_fips140_context_init(&fips_context); + if (ret < 0) { + fail("Cannot initialize FIPS context\n"); + } + + /* Read certs. */ + ret = gnutls_x509_crt_init(&client); + if (ret < 0) { + fprintf(stderr, "crt_init: %d", ret); + exit(1); + } + + ret = + gnutls_x509_crt_import(client, &client_dat, + GNUTLS_X509_FMT_PEM); + if (ret < 0) { + fprintf(stderr, "crt_import: %d", ret); + exit(1); + } + + ret = gnutls_x509_crt_init(&ca); + if (ret < 0) { + fprintf(stderr, "ca_init: %d", ret); + exit(1); + } + + ret = gnutls_x509_crt_import(ca, &ca_dat, GNUTLS_X509_FMT_PEM); + if (ret < 0) { + fprintf(stderr, "ca_import: %d", ret); + exit(1); + } + + /* Create PKCS#12 structure. */ + ret = gnutls_pkcs12_init(&pkcs12); + if (ret < 0) { + fprintf(stderr, "pkcs12_init: %d", ret); + exit(1); + } + + tests[n_tests].name = "3DES"; + tests[n_tests].crt = client; + tests[n_tests].friendly_name = "client"; + tests[n_tests].bag_encrypt_flags = GNUTLS_PKCS8_USE_PKCS12_3DES; + tests[n_tests].bag_encrypt_expected = 0; + n_tests++; + + tests[n_tests].name = "RC2-40"; + tests[n_tests].crt = ca; + tests[n_tests].friendly_name = "ca"; + tests[n_tests].bag_encrypt_flags = GNUTLS_PKCS_USE_PKCS12_RC2_40; + if (gnutls_fips140_mode_enabled()) { + tests[n_tests].bag_encrypt_expected = + GNUTLS_E_UNWANTED_ALGORITHM; + } else { + tests[n_tests].bag_encrypt_expected = 0; + } + n_tests++; + + /* Generate and add PKCS#12 cert bags. */ + for (i = 0; i < n_tests; i++) { + ret = gnutls_pkcs12_bag_init(&bag); + if (ret < 0) { + fprintf(stderr, "bag_init: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + ret = gnutls_pkcs12_bag_set_crt(bag, tests[i].crt); + if (ret < 0) { + fprintf(stderr, "set_crt: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + indx = ret; + + ret = gnutls_pkcs12_bag_set_friendly_name(bag, indx, + tests[i].friendly_name); + if (ret < 0) { + fprintf(stderr, "set_friendly_name: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + size = sizeof(key_id_buf); + ret = gnutls_x509_crt_get_key_id(tests[i].crt, 0, + key_id_buf, &size); + if (ret < 0) { + fprintf(stderr, "get_key_id: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + key_id.data = key_id_buf; + key_id.size = size; + + ret = gnutls_pkcs12_bag_set_key_id(bag, indx, &key_id); + if (ret < 0) { + fprintf(stderr, "bag_set_key_id: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + ret = gnutls_pkcs12_bag_encrypt(bag, "pass", + tests[i].bag_encrypt_flags); + if (ret != tests[i].bag_encrypt_expected) { + fprintf(stderr, "bag_encrypt: returned %d, expected %d: %s", ret, + tests[i].bag_encrypt_expected, + tests[i].name); + exit(1); + } + + ret = gnutls_pkcs12_set_bag(pkcs12, bag); + if (ret < 0) { + fprintf(stderr, "set_bag: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + gnutls_pkcs12_bag_deinit(bag); + } + + FIPS_PUSH_CONTEXT(); + + /* MAC the structure, export and print. */ + ret = gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA1, "pass"); + if (ret < 0) { + fprintf(stderr, "generate_mac: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + FIPS_POP_CONTEXT(NOT_APPROVED); + + FIPS_PUSH_CONTEXT(); + + ret = gnutls_pkcs12_verify_mac(pkcs12, "pass"); + if (ret < 0) { + fprintf(stderr, "verify_mac: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + FIPS_POP_CONTEXT(NOT_APPROVED); + + FIPS_PUSH_CONTEXT(); + + ret = gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA256, "passwd"); + if (ret < 0) { + fprintf(stderr, "generate_mac2: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + FIPS_POP_CONTEXT(NOT_APPROVED); + + FIPS_PUSH_CONTEXT(); + + ret = gnutls_pkcs12_verify_mac(pkcs12, "passwd"); + if (ret < 0) { + fprintf(stderr, "verify_mac2: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + FIPS_POP_CONTEXT(NOT_APPROVED); + + FIPS_PUSH_CONTEXT(); + + ret = gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA512, "passwd1"); + if (ret < 0) { + fprintf(stderr, "generate_mac2: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + FIPS_POP_CONTEXT(NOT_APPROVED); + + FIPS_PUSH_CONTEXT(); + + ret = gnutls_pkcs12_verify_mac(pkcs12, "passwd1"); + if (ret < 0) { + fprintf(stderr, "verify_mac2: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + FIPS_POP_CONTEXT(NOT_APPROVED); + + FIPS_PUSH_CONTEXT(); + + size = sizeof(outbuf); + ret = + gnutls_pkcs12_export(pkcs12, GNUTLS_X509_FMT_PEM, outbuf, + &size); + if (ret < 0) { + fprintf(stderr, "pkcs12_export: %s (%d)\n", gnutls_strerror(ret), ret); + exit(1); + } + + FIPS_POP_CONTEXT(NOT_APPROVED); + + if (debug) + fwrite(outbuf, size, 1, stdout); + + /* Cleanup. */ + gnutls_fips140_context_deinit(fips_context); + gnutls_pkcs12_deinit(pkcs12); + gnutls_x509_crt_deinit(client); + gnutls_x509_crt_deinit(ca); + gnutls_global_deinit(); +} |