static gnutls_x509_crt generate_ca_certificate(requiem_client_profile_t *cp, gnutls_x509_privkey key) { int ret; gnutls_x509_crt crt; unsigned int usage = 0; crt = generate_certificate(cp, key, authority_certificate_lifetime); if ( ! crt ) return NULL; usage |= GNUTLS_KEY_CRL_SIGN; usage |= GNUTLS_KEY_KEY_CERT_SIGN; usage |= GNUTLS_KEY_KEY_AGREEMENT; usage |= GNUTLS_KEY_KEY_ENCIPHERMENT; usage |= GNUTLS_KEY_DATA_ENCIPHERMENT; usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; gnutls_x509_crt_set_ca_status(crt, 1); gnutls_x509_crt_set_key_usage(crt, usage); ret = gnutls_x509_crt_sign(crt, crt, key); if ( ret < 0 ) { fprintf(stderr, "error self-signing certificate: %s.\n", gnutls_strerror(ret)); gnutls_x509_crt_deinit(crt); return NULL; } return crt; }
/*! Sets the key usage flags for the certificate. If you call this method more than once then only the last value will be used by the created certificate. */ bool CertificateBuilder::setKeyUsage(KeyUsageFlags usages) { uint usage = 0; if (usages & UsageEncipherOnly) usage |= GNUTLS_KEY_ENCIPHER_ONLY; if (usages & UsageCrlSign) usage |= GNUTLS_KEY_CRL_SIGN; if (usages & UsageKeyCertSign) usage |= GNUTLS_KEY_KEY_CERT_SIGN; if (usages & UsageKeyAgreement) usage |= GNUTLS_KEY_KEY_AGREEMENT; if (usages & UsageDataEncipherment) usage |= GNUTLS_KEY_DATA_ENCIPHERMENT; if (usages & UsageKeyEncipherment) usage |= GNUTLS_KEY_KEY_ENCIPHERMENT; if (usages & UsageNonRepudiation) usage |= GNUTLS_KEY_NON_REPUDIATION; if (usages & UsageDigitalSignature) usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; if (usages & UsageDecipherOnly) usage |= GNUTLS_KEY_DECIPHER_ONLY; d->errnumber = gnutls_x509_crt_set_key_usage(d->crt, usage); return GNUTLS_E_SUCCESS == d->errnumber; }
/* auto-generate a set of self signed certificates */ void tls_cert_generate(TALLOC_CTX *mem_ctx, const char *hostname, const char *keyfile, const char *certfile, const char *cafile) { gnutls_x509_crt cacrt, crt; gnutls_x509_privkey key, cakey; uint32_t serial = (uint32_t)time(NULL); unsigned char keyid[100]; char buf[4096]; size_t bufsize; size_t keyidsize = sizeof(keyid); time_t activation = time(NULL), expiry = activation + LIFETIME; int ret; if (file_exist(keyfile) || file_exist(certfile) || file_exist(cafile)) { DEBUG(0,("TLS autogeneration skipped - some TLS files already exist\n")); return; } #define TLSCHECK(call) do { \ ret = call; \ if (ret < 0) { \ DEBUG(0,("TLS %s - %s\n", #call, gnutls_strerror(ret))); \ goto failed; \ } \ } while (0) TLSCHECK(gnutls_global_init()); DEBUG(0,("Attempting to autogenerate TLS self-signed keys for https for hostname '%s'\n", hostname)); #if defined(HAVE_GCRYPT_H) && !defined(HAVE_GNUTLS3) DEBUG(3,("Enabling QUICK mode in gcrypt\n")); gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); #endif DEBUG(3,("Generating private key\n")); TLSCHECK(gnutls_x509_privkey_init(&key)); TLSCHECK(gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, RSA_BITS, 0)); DEBUG(3,("Generating CA private key\n")); TLSCHECK(gnutls_x509_privkey_init(&cakey)); TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, RSA_BITS, 0)); DEBUG(3,("Generating CA certificate\n")); TLSCHECK(gnutls_x509_crt_init(&cacrt)); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, ORGANISATION_NAME, strlen(ORGANISATION_NAME))); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, CA_NAME, strlen(CA_NAME))); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, GNUTLS_OID_X520_COMMON_NAME, 0, hostname, strlen(hostname))); TLSCHECK(gnutls_x509_crt_set_key(cacrt, cakey)); TLSCHECK(gnutls_x509_crt_set_serial(cacrt, &serial, sizeof(serial))); TLSCHECK(gnutls_x509_crt_set_activation_time(cacrt, activation)); TLSCHECK(gnutls_x509_crt_set_expiration_time(cacrt, expiry)); TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 1)); TLSCHECK(gnutls_x509_crt_set_key_usage(cacrt, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN)); TLSCHECK(gnutls_x509_crt_set_version(cacrt, 3)); TLSCHECK(gnutls_x509_crt_get_key_id(cacrt, 0, keyid, &keyidsize)); #if HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID TLSCHECK(gnutls_x509_crt_set_subject_key_id(cacrt, keyid, keyidsize)); #endif TLSCHECK(gnutls_x509_crt_sign2(cacrt, cacrt, cakey, GNUTLS_DIG_SHA256, 0)); DEBUG(3,("Generating TLS certificate\n")); TLSCHECK(gnutls_x509_crt_init(&crt)); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, ORGANISATION_NAME, strlen(ORGANISATION_NAME))); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, UNIT_NAME, strlen(UNIT_NAME))); TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0, hostname, strlen(hostname))); TLSCHECK(gnutls_x509_crt_set_key(crt, key)); TLSCHECK(gnutls_x509_crt_set_serial(crt, &serial, sizeof(serial))); TLSCHECK(gnutls_x509_crt_set_activation_time(crt, activation)); TLSCHECK(gnutls_x509_crt_set_expiration_time(crt, expiry)); TLSCHECK(gnutls_x509_crt_set_ca_status(crt, 0)); #ifdef GNUTLS_KP_TLS_WWW_SERVER TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0)); #endif TLSCHECK(gnutls_x509_crt_set_version(crt, 3)); TLSCHECK(gnutls_x509_crt_get_key_id(crt, 0, keyid, &keyidsize)); #if HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID TLSCHECK(gnutls_x509_crt_set_subject_key_id(crt, keyid, keyidsize)); #endif TLSCHECK(gnutls_x509_crt_sign2(crt, crt, key, GNUTLS_DIG_SHA256, 0)); TLSCHECK(gnutls_x509_crt_sign2(crt, cacrt, cakey, GNUTLS_DIG_SHA256, 0)); DEBUG(3,("Exporting TLS keys\n")); bufsize = sizeof(buf); TLSCHECK(gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buf, &bufsize)); if (!file_save(certfile, buf, bufsize)) { DEBUG(0,("Unable to save certificate in %s parent dir exists ?\n", certfile)); goto failed; } bufsize = sizeof(buf); TLSCHECK(gnutls_x509_crt_export(cacrt, GNUTLS_X509_FMT_PEM, buf, &bufsize)); if (!file_save(cafile, buf, bufsize)) { DEBUG(0,("Unable to save ca cert in %s parent dir exists ?\n", cafile)); goto failed; } bufsize = sizeof(buf); TLSCHECK(gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &bufsize)); if (!file_save_mode(keyfile, buf, bufsize, 0600)) { DEBUG(0,("Unable to save privatekey in %s parent dir exists ?\n", keyfile)); goto failed; } gnutls_x509_privkey_deinit(key); gnutls_x509_privkey_deinit(cakey); gnutls_x509_crt_deinit(cacrt); gnutls_x509_crt_deinit(crt); gnutls_global_deinit(); DEBUG(0,("TLS self-signed keys generated OK\n")); return; failed: DEBUG(0,("TLS certificate generation failed\n")); }
void doit(void) { gnutls_x509_privkey_t pkey; gnutls_x509_crt_t crt; gnutls_x509_crt_t crt2; const char *err = NULL; gnutls_datum_t out; size_t s = 0; int ret; ret = global_init(); if (ret < 0) fail("global_init\n"); gnutls_global_set_time_function(mytime); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); ret = gnutls_x509_crt_init(&crt); if (ret != 0) fail("gnutls_x509_crt_init\n"); ret = gnutls_x509_crt_init(&crt2); if (ret != 0) fail("gnutls_x509_crt_init\n"); ret = gnutls_x509_crt_import(crt2, &server_ecc_cert, GNUTLS_X509_FMT_PEM); if (ret != 0) fail("gnutls_x509_crt_import\n"); ret = gnutls_x509_privkey_init(&pkey); if (ret != 0) fail("gnutls_x509_privkey_init\n"); ret = gnutls_x509_privkey_import(pkey, &key_dat, GNUTLS_X509_FMT_PEM); if (ret != 0) fail("gnutls_x509_privkey_import\n"); /* Setup CRT */ ret = gnutls_x509_crt_set_version(crt, 3); if (ret != 0) fail("gnutls_x509_crt_set_version\n"); ret = gnutls_x509_crt_set_serial(crt, "\x0a\x11\x00", 3); if (ret != 0) fail("gnutls_x509_crt_set_serial\n"); ret = gnutls_x509_crt_set_expiration_time(crt, -1); if (ret != 0) fail("error\n"); ret = gnutls_x509_crt_set_activation_time(crt, mytime(0)); if (ret != 0) fail("error\n"); ret = gnutls_x509_crt_set_key(crt, pkey); if (ret != 0) fail("gnutls_x509_crt_set_key\n"); ret = gnutls_x509_crt_set_basic_constraints(crt, 0, -1); if (ret < 0) { fail("error\n"); } ret = gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_DIGITAL_SIGNATURE); if (ret != 0) fail("gnutls_x509_crt_set_key_usage %d\n", ret); ret = gnutls_x509_crt_set_dn(crt, "o = none to\\, mention,cn = nikos", &err); if (ret < 0) { fail("gnutls_x509_crt_set_dn: %s, %s\n", gnutls_strerror(ret), err); } ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "foo", 3, 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME, "*****@*****.**", strlen("*****@*****.**"), 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME, "ινβάλιντ@bar.org", strlen("ινβάλιντ@bar.org"), 1); if (ret != GNUTLS_E_INVALID_UTF8_EMAIL) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS, "\xc1\x5c\x96\x3", 4, 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16, 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "apa", 3, 0); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "απαλό.com", strlen("απαλό.com"), 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); #ifdef HAVE_LIBIDN ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME, "test@νίκο.org", strlen("test@νίκο.org"), 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); #endif s = 0; ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL); if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0); if (ret != 0) fail("gnutls_x509_crt_set_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_CLIENT, 1); if (ret != 0) fail("gnutls_x509_crt_set_key_purpose_oid2 %d\n", ret); ret = gnutls_x509_crt_set_issuer_dn(crt, "cn = my CA, o = big\\, and one", &err); if (ret < 0) { fail("gnutls_x509_crt_set_issuer_dn: %s, %s\n", gnutls_strerror(ret), err); } ret = gnutls_x509_crt_sign2(crt, crt, pkey, GNUTLS_DIG_SHA256, 0); if (ret < 0) fail("gnutls_x509_crt_sign2: %s\n", gnutls_strerror(ret)); ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, &out); if (ret != 0) fail("gnutls_x509_crt_print\n"); if (debug) printf("crt: %.*s\n", out.size, out.data); gnutls_free(out.data); s = 0; ret = gnutls_x509_crt_get_extension_info(crt, 0, NULL, &s, NULL); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) fail("gnutls_x509_crt_get_extension_info2: %s\n", strerror(ret)); s = 0; ret = gnutls_x509_crt_get_extension_data(crt, 0, NULL, &s); if (ret != 0) fail("gnutls_x509_crt_get_extension_data: %s\n", strerror(ret)); ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &out); if (ret < 0 || out.size == 0) fail("gnutls_x509_crt_get_raw_issuer_dn: %s\n", gnutls_strerror(ret)); if (out.size != 45 || memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) { hexprint(out.data, out.size); fail("issuer DN comparison failed\n"); } gnutls_free(out.data); ret = gnutls_x509_crt_get_raw_dn(crt, &out); if (ret < 0 || out.size == 0) fail("gnutls_x509_crt_get_raw_dn: %s\n", gnutls_strerror(ret)); if (out.size != 45 || memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) { fail("DN comparison failed\n"); } gnutls_free(out.data); ret = gnutls_x509_crt_equals(crt, crt); if (ret == 0) { fail("equality test failed\n"); } ret = gnutls_x509_crt_equals(crt, crt2); if (ret != 0) { fail("equality test failed\n"); } assert(gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &out) >= 0); #ifdef HAVE_LIBIDN assert(out.size == saved_crt.size); assert(memcmp(out.data, saved_crt.data, out.size)==0); #endif gnutls_free(out.data); gnutls_x509_crt_deinit(crt); gnutls_x509_crt_deinit(crt2); gnutls_x509_privkey_deinit(pkey); gnutls_global_deinit(); }
static int /* O - 1 on success, 0 on failure */ make_certificate(cupsd_client_t *con) /* I - Client connection */ { gnutls_x509_crt crt; /* Self-signed certificate */ gnutls_x509_privkey key; /* Encryption key */ cups_lang_t *language; /* Default language info */ cups_file_t *fp; /* Key/cert file */ unsigned char buffer[8192]; /* Buffer for x509 data */ size_t bytes; /* Number of bytes of data */ unsigned char serial[4]; /* Serial number buffer */ time_t curtime; /* Current time */ int result; /* Result of GNU TLS calls */ /* * Create the encryption key... */ cupsdLogMessage(CUPSD_LOG_INFO, "Generating SSL server key..."); gnutls_x509_privkey_init(&key); gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0); /* * Save it... */ bytes = sizeof(buffer); if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server key - %s", gnutls_strerror(result)); gnutls_x509_privkey_deinit(key); return (0); } else if ((fp = cupsFileOpen(ServerKey, "w")) != NULL) { cupsFileWrite(fp, (char *)buffer, bytes); cupsFileClose(fp); cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...", ServerKey); } else { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create SSL server key file \"%s\" - %s", ServerKey, strerror(errno)); gnutls_x509_privkey_deinit(key); return (0); } /* * Create the self-signed certificate... */ cupsdLogMessage(CUPSD_LOG_INFO, "Generating self-signed SSL certificate..."); language = cupsLangDefault(); curtime = time(NULL); serial[0] = curtime >> 24; serial[1] = curtime >> 16; serial[2] = curtime >> 8; serial[3] = curtime; gnutls_x509_crt_init(&crt); if (strlen(language->language) == 5) gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, language->language + 3, 2); else gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, "US", 2); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0, ServerName, strlen(ServerName)); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, ServerName, strlen(ServerName)); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0, ServerAdmin, strlen(ServerAdmin)); gnutls_x509_crt_set_key(crt, key); gnutls_x509_crt_set_serial(crt, serial, sizeof(serial)); gnutls_x509_crt_set_activation_time(crt, curtime); gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400); gnutls_x509_crt_set_ca_status(crt, 0); gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME, ServerName); gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0); gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT); gnutls_x509_crt_set_version(crt, 3); bytes = sizeof(buffer); if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0) gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes); gnutls_x509_crt_sign(crt, crt, key); /* * Save it... */ bytes = sizeof(buffer); if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0) cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server certificate - %s", gnutls_strerror(result)); else if ((fp = cupsFileOpen(ServerCertificate, "w")) != NULL) { cupsFileWrite(fp, (char *)buffer, bytes); cupsFileClose(fp); cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server certificate file \"%s\"...", ServerCertificate); } else cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create SSL server certificate file \"%s\" - %s", ServerCertificate, strerror(errno)); /* * Cleanup... */ gnutls_x509_crt_deinit(crt); gnutls_x509_privkey_deinit(key); return (1); }
/** Private function which generate private keys and certificates. * * @return 1 if keys were successfully generated, 0 otherwise */ static userpref_error_t userpref_gen_keys_and_cert(void) { userpref_error_t ret = USERPREF_E_SSL_ERROR; gnutls_x509_privkey_t root_privkey; gnutls_x509_crt_t root_cert; gnutls_x509_privkey_t host_privkey; gnutls_x509_crt_t host_cert; gnutls_global_deinit(); gnutls_global_init(); //use less secure random to speed up key generation gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM); gnutls_x509_privkey_init(&root_privkey); gnutls_x509_privkey_init(&host_privkey); gnutls_x509_crt_init(&root_cert); gnutls_x509_crt_init(&host_cert); /* generate root key */ gnutls_x509_privkey_generate(root_privkey, GNUTLS_PK_RSA, 2048, 0); gnutls_x509_privkey_generate(host_privkey, GNUTLS_PK_RSA, 2048, 0); /* generate certificates */ gnutls_x509_crt_set_key(root_cert, root_privkey); gnutls_x509_crt_set_serial(root_cert, "\x00", 1); gnutls_x509_crt_set_version(root_cert, 3); gnutls_x509_crt_set_ca_status(root_cert, 1); gnutls_x509_crt_set_activation_time(root_cert, time(NULL)); gnutls_x509_crt_set_expiration_time(root_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); gnutls_x509_crt_sign(root_cert, root_cert, root_privkey); gnutls_x509_crt_set_key(host_cert, host_privkey); gnutls_x509_crt_set_serial(host_cert, "\x00", 1); gnutls_x509_crt_set_version(host_cert, 3); gnutls_x509_crt_set_ca_status(host_cert, 0); gnutls_x509_crt_set_key_usage(host_cert, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE); gnutls_x509_crt_set_activation_time(host_cert, time(NULL)); gnutls_x509_crt_set_expiration_time(host_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); gnutls_x509_crt_sign(host_cert, root_cert, root_privkey); /* export to PEM format */ size_t root_key_export_size = 0; size_t host_key_export_size = 0; gnutls_datum_t root_key_pem = { NULL, 0 }; gnutls_datum_t host_key_pem = { NULL, 0 }; gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, NULL, &root_key_export_size); gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, NULL, &host_key_export_size); root_key_pem.data = gnutls_malloc(root_key_export_size); host_key_pem.data = gnutls_malloc(host_key_export_size); gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, root_key_pem.data, &root_key_export_size); root_key_pem.size = root_key_export_size; gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, host_key_pem.data, &host_key_export_size); host_key_pem.size = host_key_export_size; size_t root_cert_export_size = 0; size_t host_cert_export_size = 0; gnutls_datum_t root_cert_pem = { NULL, 0 }; gnutls_datum_t host_cert_pem = { NULL, 0 }; gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, NULL, &root_cert_export_size); gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, NULL, &host_cert_export_size); root_cert_pem.data = gnutls_malloc(root_cert_export_size); host_cert_pem.data = gnutls_malloc(host_cert_export_size); gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, root_cert_pem.data, &root_cert_export_size); root_cert_pem.size = root_cert_export_size; gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, host_cert_pem.data, &host_cert_export_size); host_cert_pem.size = host_cert_export_size; if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && NULL != host_cert_pem.data && 0 != host_cert_pem.size) ret = USERPREF_E_SUCCESS; /* store values in config file */ userpref_set_keys_and_certs( &root_key_pem, &root_cert_pem, &host_key_pem, &host_cert_pem); gnutls_free(root_key_pem.data); gnutls_free(root_cert_pem.data); gnutls_free(host_key_pem.data); gnutls_free(host_cert_pem.data); //restore gnutls env gnutls_global_deinit(); gnutls_global_init(); return ret; }
void Plugin::_loadCertificate() { QFile file(this->crtFile); gnutls_datum_t datum; size_t size = 2048; QByteArray data; gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; gnutls_pubkey_t pubkeyCrt; int error; QMap<char *, QByteArray> oid; gnutls_digest_algorithm_t digest; if (!file.open(QIODevice::ReadWrite)) throw Properties("error", "Unable to open the certificate file").add("file", this->crtFile); ASSERT_INIT(gnutls_x509_crt_init(&this->crt), "crt"); ASSERT(gnutls_privkey_init(&privkey)); ASSERT(gnutls_privkey_import_x509(privkey, this->key, 0)); ASSERT(gnutls_pubkey_init(&pubkey)); ASSERT(gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0)); // Verifies that the certificate is valid if (file.size() > 0) { ASSERT(gnutls_pubkey_init(&pubkeyCrt)); data = file.readAll(); datum.size = data.size(); datum.data = (unsigned char *)data.data(); if (gnutls_x509_crt_import(this->crt, &datum, GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS) file.resize(0); else if (gnutls_x509_crt_get_expiration_time(this->crt) < ::time(NULL) + CRT_EXPIRATION_REGEN) file.resize(0); else if (gnutls_pubkey_import_x509(pubkeyCrt, this->crt, 0) != GNUTLS_E_SUCCESS) file.resize(0); // Ensures that the public keys of the certificate and the private key match size_t size1 = size, size2 = size; QByteArray pub1((int)size1, 0), pub2((int)size2, 0); if (gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_PEM, pub1.data(), &size1) != GNUTLS_E_SUCCESS || gnutls_pubkey_export(pubkeyCrt, GNUTLS_X509_FMT_PEM, pub2.data(), &size2) != GNUTLS_E_SUCCESS || size1 != size2 || pub1 != pub2) file.resize(0); gnutls_pubkey_deinit(pubkeyCrt); } // Generates a new certificate if (file.size() == 0) { gnutls_x509_crt_deinit(this->crt); this->init.removeAll("crt"); ASSERT_INIT(gnutls_x509_crt_init(&this->crt), "crt"); LOG_INFO("Generating a new certificate", "Plugin", "_generateCertificate"); oid.insert((char *)GNUTLS_OID_X520_COMMON_NAME, "LightBird"); oid.insert((char *)GNUTLS_OID_X520_ORGANIZATION_NAME, "LightBird"); QMapIterator<char *, QByteArray> it(oid); while (it.hasNext()) ASSERT(gnutls_x509_crt_set_dn_by_oid(this->crt, it.key(), 0, it.value().data(), it.next().value().size())); ASSERT(gnutls_x509_crt_set_pubkey(this->crt, pubkey)); data = this->_generateSerial(); ASSERT(gnutls_x509_crt_set_serial(this->crt, data.data(), data.size())); ASSERT(gnutls_x509_crt_set_activation_time(this->crt, ::time(NULL))); ASSERT(gnutls_x509_crt_set_expiration_time(this->crt, ::time(NULL) + CRT_EXPIRATION)); ASSERT(gnutls_x509_crt_set_basic_constraints(this->crt, 0, -1)); ASSERT(gnutls_x509_crt_set_key_purpose_oid(this->crt, GNUTLS_KP_TLS_WWW_SERVER, 0)); ASSERT(gnutls_x509_crt_set_key_usage(this->crt, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT)); data.resize((int)size); ASSERT(gnutls_x509_crt_get_key_id(this->crt, 0, (unsigned char *)data.data(), &size)); ASSERT(gnutls_x509_crt_set_subject_key_id(this->crt, (unsigned char *)data.data(), size)); ASSERT(gnutls_x509_crt_set_version(this->crt, 3)); ASSERT(gnutls_pubkey_get_preferred_hash_algorithm(pubkey, &digest, NULL)); ASSERT(gnutls_x509_crt_privkey_sign(this->crt, this->crt, privkey, digest, 0)); size = data.size(); ASSERT(gnutls_x509_crt_export(this->crt, GNUTLS_X509_FMT_PEM, data.data(), &size)); data.resize((int)size); file.write(data); } gnutls_pubkey_deinit(pubkey); gnutls_privkey_deinit(privkey); }
crypto::Identity generateIdentity(const std::string& name, crypto::Identity ca) { int rc = gnutls_global_init(); if (rc != GNUTLS_E_SUCCESS) return {}; auto shared_key = std::make_shared<PrivateKey>(PrivateKey::generate()); gnutls_x509_crt_t cert; if (gnutls_x509_crt_init(&cert) != GNUTLS_E_SUCCESS) return {}; auto shared_crt = std::make_shared<Certificate>(cert); gnutls_x509_crt_set_activation_time(cert, time(NULL)); gnutls_x509_crt_set_expiration_time(cert, time(NULL) + (700 * 24 * 60 * 60)); if (gnutls_x509_crt_set_key(cert, shared_key->x509_key) != GNUTLS_E_SUCCESS) { std::cerr << "Error when setting certificate key" << std::endl; return {}; } if (gnutls_x509_crt_set_version(cert, 3) != GNUTLS_E_SUCCESS) { std::cerr << "Error when setting certificate version" << std::endl; return {}; } // TODO: compute the subject key using the recommended RFC method auto pk_id = shared_key->getPublicKey().getId(); gnutls_x509_crt_set_subject_key_id(cert, &pk_id, sizeof(pk_id)); gnutls_x509_crt_set_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, name.data(), name.length()); const std::string& uid_str = shared_key->getPublicKey().getId().toString(); gnutls_x509_crt_set_dn_by_oid(cert, GNUTLS_OID_LDAP_UID, 0, uid_str.data(), uid_str.length()); { random_device rdev; std::uniform_int_distribution<uint64_t> dist{}; uint64_t cert_serial = dist(rdev); gnutls_x509_crt_set_serial(cert, &cert_serial, sizeof(cert_serial)); } if (ca.first && ca.second) { gnutls_x509_crt_set_key_usage (cert, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_DATA_ENCIPHERMENT); //if (gnutls_x509_crt_sign2(cert, ca.second->cert, ca.first->x509_key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) { if (gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) { std::cerr << "Error when signing certificate" << std::endl; return {}; } shared_crt->issuer = ca.second; } else { gnutls_x509_crt_set_ca_status(cert, 1); gnutls_x509_crt_set_key_usage (cert, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_CERT_SIGN); //if (gnutls_x509_crt_sign2(cert, cert, key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) { if (gnutls_x509_crt_privkey_sign(cert, cert, shared_key->key, get_dig(cert), 0) != GNUTLS_E_SUCCESS) { std::cerr << "Error when signing certificate" << std::endl; return {}; } } gnutls_global_deinit(); return {shared_key, shared_crt}; }
int /* O - 1 on success, 0 on failure */ cupsMakeServerCredentials( const char *path, /* I - Path to keychain/directory */ const char *common_name, /* I - Common name */ int num_alt_names, /* I - Number of subject alternate names */ const char **alt_names, /* I - Subject Alternate Names */ time_t expiration_date) /* I - Expiration date */ { gnutls_x509_crt_t crt; /* Self-signed certificate */ gnutls_x509_privkey_t key; /* Encryption private key */ char temp[1024], /* Temporary directory name */ crtfile[1024], /* Certificate filename */ keyfile[1024]; /* Private key filename */ cups_lang_t *language; /* Default language info */ cups_file_t *fp; /* Key/cert file */ unsigned char buffer[8192]; /* Buffer for x509 data */ size_t bytes; /* Number of bytes of data */ unsigned char serial[4]; /* Serial number buffer */ time_t curtime; /* Current time */ int result; /* Result of GNU TLS calls */ DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date)); /* * Filenames... */ if (!path) path = http_gnutls_default_path(temp, sizeof(temp)); if (!path || !common_name) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); return (0); } http_gnutls_make_path(crtfile, sizeof(crtfile), path, common_name, "crt"); http_gnutls_make_path(keyfile, sizeof(keyfile), path, common_name, "key"); /* * Create the encryption key... */ DEBUG_puts("1cupsMakeServerCredentials: Creating key pair."); gnutls_x509_privkey_init(&key); gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0); DEBUG_puts("1cupsMakeServerCredentials: Key pair created."); /* * Save it... */ bytes = sizeof(buffer); if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0) { DEBUG_printf(("1cupsMakeServerCredentials: Unable to export private key: %s", gnutls_strerror(result))); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(result), 0); gnutls_x509_privkey_deinit(key); return (0); } else if ((fp = cupsFileOpen(keyfile, "w")) != NULL) { DEBUG_printf(("1cupsMakeServerCredentials: Writing private key to \"%s\".", keyfile)); cupsFileWrite(fp, (char *)buffer, bytes); cupsFileClose(fp); } else { DEBUG_printf(("1cupsMakeServerCredentials: Unable to create private key file \"%s\": %s", keyfile, strerror(errno))); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0); gnutls_x509_privkey_deinit(key); return (0); } /* * Create the self-signed certificate... */ DEBUG_puts("1cupsMakeServerCredentials: Generating self-signed X.509 certificate."); language = cupsLangDefault(); curtime = time(NULL); serial[0] = curtime >> 24; serial[1] = curtime >> 16; serial[2] = curtime >> 8; serial[3] = curtime; gnutls_x509_crt_init(&crt); if (strlen(language->language) == 5) gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, language->language + 3, 2); else gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, "US", 2); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0, common_name, strlen(common_name)); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, common_name, strlen(common_name)); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0, "Unknown", 7); /* gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0, ServerAdmin, strlen(ServerAdmin));*/ gnutls_x509_crt_set_key(crt, key); gnutls_x509_crt_set_serial(crt, serial, sizeof(serial)); gnutls_x509_crt_set_activation_time(crt, curtime); gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400); gnutls_x509_crt_set_ca_status(crt, 0); if (num_alt_names > 0) gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME, alt_names[0]); gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0); gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT); gnutls_x509_crt_set_version(crt, 3); bytes = sizeof(buffer); if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0) gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes); gnutls_x509_crt_sign(crt, crt, key); /* * Save it... */ bytes = sizeof(buffer); if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0) { DEBUG_printf(("1cupsMakeServerCredentials: Unable to export public key and X.509 certificate: %s", gnutls_strerror(result))); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(result), 0); gnutls_x509_crt_deinit(crt); gnutls_x509_privkey_deinit(key); return (0); } else if ((fp = cupsFileOpen(crtfile, "w")) != NULL) { DEBUG_printf(("1cupsMakeServerCredentials: Writing public key and X.509 certificate to \"%s\".", crtfile)); cupsFileWrite(fp, (char *)buffer, bytes); cupsFileClose(fp); } else { DEBUG_printf(("1cupsMakeServerCredentials: Unable to create public key and X.509 certificate file \"%s\": %s", crtfile, strerror(errno))); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0); gnutls_x509_crt_deinit(crt); gnutls_x509_privkey_deinit(key); return (0); } /* * Cleanup... */ gnutls_x509_crt_deinit(crt); gnutls_x509_privkey_deinit(key); DEBUG_puts("1cupsMakeServerCredentials: Successfully created credentials."); return (1); }
void doit(void) { gnutls_x509_privkey_t pkey; gnutls_x509_crt_t crt; gnutls_x509_crt_t crt2; const char *err = NULL; unsigned char buf[64]; gnutls_datum_t out; size_t s = 0; int ret; ret = global_init(); if (ret < 0) fail("global_init\n"); gnutls_global_set_time_function(mytime); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); ret = gnutls_x509_crt_init(&crt); if (ret != 0) fail("gnutls_x509_crt_init\n"); ret = gnutls_x509_crt_init(&crt2); if (ret != 0) fail("gnutls_x509_crt_init\n"); ret = gnutls_x509_crt_import(crt2, &server_ecc_cert, GNUTLS_X509_FMT_PEM); if (ret != 0) fail("gnutls_x509_crt_import\n"); ret = gnutls_x509_privkey_init(&pkey); if (ret != 0) fail("gnutls_x509_privkey_init\n"); ret = gnutls_x509_privkey_import(pkey, &key_dat, GNUTLS_X509_FMT_PEM); if (ret != 0) fail("gnutls_x509_privkey_import\n"); /* Setup CRT */ ret = gnutls_x509_crt_set_version(crt, 3); if (ret != 0) fail("gnutls_x509_crt_set_version\n"); ret = gnutls_x509_crt_set_serial(crt, "\x0a\x11\x00", 3); if (ret != 0) fail("gnutls_x509_crt_set_serial\n"); ret = gnutls_x509_crt_set_expiration_time(crt, -1); if (ret != 0) fail("error\n"); ret = gnutls_x509_crt_set_activation_time(crt, mytime(0)); if (ret != 0) fail("error\n"); ret = gnutls_x509_crt_set_key(crt, pkey); if (ret != 0) fail("gnutls_x509_crt_set_key\n"); ret = gnutls_x509_crt_set_basic_constraints(crt, 0, -1); if (ret < 0) { fail("error\n"); } ret = gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_DIGITAL_SIGNATURE); if (ret != 0) fail("gnutls_x509_crt_set_key_usage %d\n", ret); ret = gnutls_x509_crt_set_dn(crt, "o = none to\\, mention,cn = nikos", &err); if (ret < 0) { fail("gnutls_x509_crt_set_dn: %s, %s\n", gnutls_strerror(ret), err); } ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "foo", 3, 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME, "*****@*****.**", strlen("*****@*****.**"), 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME, "ινβάλιντ@bar.org", strlen("ινβάλιντ@bar.org"), 1); if (ret != GNUTLS_E_INVALID_UTF8_EMAIL) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS, "\xc1\x5c\x96\x3", 4, 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16, 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "apa", 3, 0); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME, "απαλό.com", strlen("απαλό.com"), 1); #if defined(HAVE_LIBIDN2) || defined(HAVE_LIBIDN) if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name: %s\n", gnutls_strerror(ret)); ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME, "test@νίκο.org", strlen("test@νίκο.org"), 1); if (ret != 0) fail("gnutls_x509_crt_set_subject_alt_name\n"); #else if (ret != GNUTLS_E_UNIMPLEMENTED_FEATURE) fail("gnutls_x509_crt_set_subject_alt_name: %s\n", gnutls_strerror(ret)); #endif s = 0; ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL); if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0); if (ret != 0) fail("gnutls_x509_crt_set_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret); s = 0; ret = gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_CLIENT, 1); if (ret != 0) fail("gnutls_x509_crt_set_key_purpose_oid2 %d\n", ret); /* in the end this will be ignored as the issuer will be set * by gnutls_x509_crt_sign2() */ ret = gnutls_x509_crt_set_issuer_dn(crt, "cn = my CA, o = big\\, and one", &err); if (ret < 0) { fail("gnutls_x509_crt_set_issuer_dn: %s, %s\n", gnutls_strerror(ret), err); } #define ISSUER_UNIQUE_ID "\x00\x01\x02\x03" #define SUBJECT_UNIQUE_ID "\x04\x03\x02\x01" ret = gnutls_x509_crt_set_issuer_unique_id(crt, ISSUER_UNIQUE_ID, sizeof(ISSUER_UNIQUE_ID)-1); if (ret < 0) fail("error: %s\n", gnutls_strerror(ret)); ret = gnutls_x509_crt_set_subject_unique_id(crt, SUBJECT_UNIQUE_ID, sizeof(SUBJECT_UNIQUE_ID)-1); if (ret < 0) fail("error: %s\n", gnutls_strerror(ret)); /* Sign and finalize the certificate */ ret = gnutls_x509_crt_sign2(crt, crt, pkey, GNUTLS_DIG_SHA256, 0); if (ret < 0) fail("gnutls_x509_crt_sign2: %s\n", gnutls_strerror(ret)); ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, &out); if (ret != 0) fail("gnutls_x509_crt_print\n"); if (debug) printf("crt: %.*s\n", out.size, out.data); gnutls_free(out.data); /* Verify whether selected input is present */ s = 0; ret = gnutls_x509_crt_get_extension_info(crt, 0, NULL, &s, NULL); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) fail("gnutls_x509_crt_get_extension_info2: %s\n", strerror(ret)); s = 0; ret = gnutls_x509_crt_get_extension_data(crt, 0, NULL, &s); if (ret != 0) fail("gnutls_x509_crt_get_extension_data: %s\n", strerror(ret)); ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &out); if (ret < 0 || out.size == 0) fail("gnutls_x509_crt_get_raw_issuer_dn: %s\n", gnutls_strerror(ret)); if (out.size != 45 || memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) { hexprint(out.data, out.size); fail("issuer DN comparison failed\n"); } gnutls_free(out.data); s = sizeof(buf); ret = gnutls_x509_crt_get_issuer_unique_id(crt, (void*)buf, &s); if (ret < 0) fail("error: %s\n", gnutls_strerror(ret)); if (s != sizeof(ISSUER_UNIQUE_ID)-1 || memcmp(buf, ISSUER_UNIQUE_ID, s) != 0) { fail("issuer unique id comparison failed\n"); } s = sizeof(buf); ret = gnutls_x509_crt_get_subject_unique_id(crt, (void*)buf, &s); if (ret < 0) fail("error: %s\n", gnutls_strerror(ret)); if (s != sizeof(SUBJECT_UNIQUE_ID)-1 || memcmp(buf, SUBJECT_UNIQUE_ID, s) != 0) { fail("subject unique id comparison failed\n"); } ret = gnutls_x509_crt_get_raw_dn(crt, &out); if (ret < 0 || out.size == 0) fail("gnutls_x509_crt_get_raw_dn: %s\n", gnutls_strerror(ret)); if (out.size != 45 || memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) { fail("DN comparison failed\n"); } gnutls_free(out.data); ret = gnutls_x509_crt_equals(crt, crt); if (ret == 0) { fail("equality test failed\n"); } ret = gnutls_x509_crt_equals(crt, crt2); if (ret != 0) { fail("equality test failed\n"); } assert(gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &out) >= 0); if (debug) fprintf(stderr, "%s\n", out.data); #if defined(HAVE_LIBIDN2) assert(out.size == saved_crt.size); assert(memcmp(out.data, saved_crt.data, out.size)==0); #endif gnutls_free(out.data); gnutls_x509_crt_deinit(crt); gnutls_x509_crt_deinit(crt2); gnutls_x509_privkey_deinit(pkey); gnutls_global_deinit(); }