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; }
static gnutls_x509_crt generate_certificate(requiem_client_profile_t *cp, gnutls_x509_privkey key, int expire) { int ret; char buf[1024]; gnutls_x509_crt crt; uint64_t analyzerid; size_t size = sizeof(buf); ret = gnutls_x509_crt_init(&crt); if ( ret < 0 ) { fprintf(stderr, "error creating x509 certificate: %s.\n", gnutls_strerror(ret)); return NULL; } if ( ! expire ) expire = 0x7fffffff; else expire = time(NULL) + expire * 24 * 60 * 60; gnutls_x509_crt_set_version(crt, 3); gnutls_x509_crt_set_ca_status(crt, 0); gnutls_x509_crt_set_activation_time(crt, time(NULL)); gnutls_x509_crt_set_expiration_time(crt, expire); analyzerid = requiem_client_profile_get_analyzerid(cp); ret = snprintf(buf, sizeof(buf), "%" REQUIEM_PRIu64, analyzerid); ret = gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_DN_QUALIFIER, 0, buf, ret); if ( ret < 0 ) { fprintf(stderr, "error setting common name: %s.\n", gnutls_strerror(ret)); return NULL; } gnutls_x509_crt_set_serial(crt, &analyzerid, sizeof(analyzerid)); if ( ! key ) return crt; gnutls_x509_crt_set_key(crt, key); ret = gnutls_x509_crt_get_key_id(crt, 0, (unsigned char *) buf, &size); if ( ret == 0 ) { ret = gnutls_x509_crt_set_subject_key_id(crt, buf, size); if ( ret < 0 ) { gnutls_x509_crt_deinit(crt); fprintf(stderr, "error setting subject key ID: %s\n", gnutls_strerror(ret)); return NULL; } } return crt; }
/* 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")); }
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; }
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); }