summaryrefslogtreecommitdiffstats
path: root/tests/pkcs12_encode.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 07:33:12 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 07:33:12 +0000
commit36082a2fe36ecd800d784ae44c14f1f18c66a7e9 (patch)
tree6c68e0c0097987aff85a01dabddd34b862309a7c /tests/pkcs12_encode.c
parentInitial commit. (diff)
downloadgnutls28-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.c331
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();
+}