bool ret = false; // Return value
gnutls_x509_crt_t crt = NULL; // New certificate
gnutls_x509_privkey_t key = NULL; // Encryption private key
+ gnutls_pubkey_t pubkey = NULL; // Encryption public key
gnutls_x509_crt_t root_crt = NULL;// Root certificate
gnutls_x509_privkey_t root_key = NULL;// Root private key
char defpath[1024], // Default path
crtfile[1024], // Certificate filename
keyfile[1024], // Private key filename
+ pubfile[1024], // Public key filename
*root_crtdata, // Root certificate data
*root_keydata; // Root private key data
unsigned gnutls_usage = 0;// GNU TLS keyUsage bits
http_make_path(crtfile, sizeof(crtfile), path, common_name, "crt");
http_make_path(keyfile, sizeof(keyfile), path, common_name, "key");
+ http_make_path(pubfile, sizeof(pubfile), path, common_name, "pub");
+
+ // Key usage flags...
+ if (usage & CUPS_CREDUSAGE_DIGITAL_SIGNATURE)
+ gnutls_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
+ if (usage & CUPS_CREDUSAGE_NON_REPUDIATION)
+ gnutls_usage |= GNUTLS_KEY_NON_REPUDIATION;
+ if (usage & CUPS_CREDUSAGE_KEY_ENCIPHERMENT)
+ gnutls_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
+ if (usage & CUPS_CREDUSAGE_DATA_ENCIPHERMENT)
+ gnutls_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
+ if (usage & CUPS_CREDUSAGE_KEY_AGREEMENT)
+ gnutls_usage |= GNUTLS_KEY_KEY_AGREEMENT;
+ if (usage & CUPS_CREDUSAGE_KEY_CERT_SIGN)
+ gnutls_usage |= GNUTLS_KEY_KEY_CERT_SIGN;
+ if (usage & CUPS_CREDUSAGE_CRL_SIGN)
+ gnutls_usage |= GNUTLS_KEY_CRL_SIGN;
+ if (usage & CUPS_CREDUSAGE_ENCIPHER_ONLY)
+ gnutls_usage |= GNUTLS_KEY_ENCIPHER_ONLY;
+ if (usage & CUPS_CREDUSAGE_DECIPHER_ONLY)
+ gnutls_usage |= GNUTLS_KEY_DECIPHER_ONLY;
// Create the encryption key...
DEBUG_puts("1cupsCreateCredentials: Creating key pair.");
goto done;
}
+ bytes = sizeof(buffer);
+
+ if ((err = gnutls_pubkey_init(&pubkey)) < 0)
+ {
+ DEBUG_printf("1cupsCreateCredentials: Unable to create public key: %s", gnutls_strerror(err));
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(err), 0);
+ goto done;
+ }
+ else if ((err = gnutls_pubkey_import_privkey(pubkey, key, gnutls_usage, /*flags*/0)) < 0)
+ {
+ DEBUG_printf("1cupsCreateCredentials: Unable to import public key: %s", gnutls_strerror(err));
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(err), 0);
+ goto done;
+ }
+ else if ((err = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0)
+ {
+ DEBUG_printf("1cupsCreateCredentials: Unable to export public key: %s", gnutls_strerror(err));
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(err), 0);
+ goto done;
+ }
+ else if ((fp = cupsFileOpen(pubfile, "w")) != NULL)
+ {
+ DEBUG_printf("1cupsCreateCredentials: Writing public key to \"%s\".", keyfile);
+ cupsFileWrite(fp, (char *)buffer, bytes);
+ cupsFileClose(fp);
+ }
+ else
+ {
+ DEBUG_printf("1cupsCreateCredentials: Unable to create public key file \"%s\": %s", keyfile, strerror(errno));
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
+ goto done;
+ }
+
// Create the certificate...
DEBUG_puts("1cupsCreateCredentials: Generating X.509 certificate.");
if (purpose & CUPS_CREDPURPOSE_OCSP_SIGNING)
gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_OCSP_SIGNING, 0);
- if (usage & CUPS_CREDUSAGE_DIGITAL_SIGNATURE)
- gnutls_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
- if (usage & CUPS_CREDUSAGE_NON_REPUDIATION)
- gnutls_usage |= GNUTLS_KEY_NON_REPUDIATION;
- if (usage & CUPS_CREDUSAGE_KEY_ENCIPHERMENT)
- gnutls_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
- if (usage & CUPS_CREDUSAGE_DATA_ENCIPHERMENT)
- gnutls_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
- if (usage & CUPS_CREDUSAGE_KEY_AGREEMENT)
- gnutls_usage |= GNUTLS_KEY_KEY_AGREEMENT;
- if (usage & CUPS_CREDUSAGE_KEY_CERT_SIGN)
- gnutls_usage |= GNUTLS_KEY_KEY_CERT_SIGN;
- if (usage & CUPS_CREDUSAGE_CRL_SIGN)
- gnutls_usage |= GNUTLS_KEY_CRL_SIGN;
- if (usage & CUPS_CREDUSAGE_ENCIPHER_ONLY)
- gnutls_usage |= GNUTLS_KEY_ENCIPHER_ONLY;
- if (usage & CUPS_CREDUSAGE_DECIPHER_ONLY)
- gnutls_usage |= GNUTLS_KEY_DECIPHER_ONLY;
-
gnutls_x509_crt_set_key_usage(crt, gnutls_usage);
gnutls_x509_crt_set_version(crt, 3);
gnutls_x509_crt_deinit(crt);
if (key)
gnutls_x509_privkey_deinit(key);
+ if (pubkey)
+ gnutls_pubkey_deinit(pubkey);
return (ret);
}
bool ret = false; // Return value
gnutls_x509_crq_t crq = NULL; // Certificate request
gnutls_x509_privkey_t key = NULL; // Private/public key pair
+ gnutls_pubkey_t pubkey = NULL; // Encryption public key
char defpath[1024], // Default path
csrfile[1024], // Certificate signing request filename
- keyfile[1024]; // Private key filename
+ keyfile[1024], // Private key filename
+ pubfile[1024]; // Public key filename
unsigned gnutls_usage = 0;// GNU TLS keyUsage bits
cups_file_t *fp; // Key/cert file
unsigned char buffer[8192]; // Buffer for key/cert data
http_make_path(csrfile, sizeof(csrfile), path, common_name, "csr");
http_make_path(keyfile, sizeof(keyfile), path, common_name, "ktm");
+ http_make_path(pubfile, sizeof(pubfile), path, common_name, "pub");
+
+ // Key usage flags...
+ if (usage & CUPS_CREDUSAGE_DIGITAL_SIGNATURE)
+ gnutls_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
+ if (usage & CUPS_CREDUSAGE_NON_REPUDIATION)
+ gnutls_usage |= GNUTLS_KEY_NON_REPUDIATION;
+ if (usage & CUPS_CREDUSAGE_KEY_ENCIPHERMENT)
+ gnutls_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
+ if (usage & CUPS_CREDUSAGE_DATA_ENCIPHERMENT)
+ gnutls_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
+ if (usage & CUPS_CREDUSAGE_KEY_AGREEMENT)
+ gnutls_usage |= GNUTLS_KEY_KEY_AGREEMENT;
+ if (usage & CUPS_CREDUSAGE_KEY_CERT_SIGN)
+ gnutls_usage |= GNUTLS_KEY_KEY_CERT_SIGN;
+ if (usage & CUPS_CREDUSAGE_CRL_SIGN)
+ gnutls_usage |= GNUTLS_KEY_CRL_SIGN;
+ if (usage & CUPS_CREDUSAGE_ENCIPHER_ONLY)
+ gnutls_usage |= GNUTLS_KEY_ENCIPHER_ONLY;
+ if (usage & CUPS_CREDUSAGE_DECIPHER_ONLY)
+ gnutls_usage |= GNUTLS_KEY_DECIPHER_ONLY;
// Create the encryption key...
DEBUG_puts("1cupsCreateCredentialsRequest: Creating key pair.");
goto done;
}
- // Create the certificate...
+ bytes = sizeof(buffer);
+
+ if ((err = gnutls_pubkey_init(&pubkey)) < 0)
+ {
+ DEBUG_printf("1cupsCreateCredentials: Unable to create public key: %s", gnutls_strerror(err));
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(err), 0);
+ goto done;
+ }
+ else if ((err = gnutls_pubkey_import_privkey(pubkey, key, gnutls_usage, /*flags*/0)) < 0)
+ {
+ DEBUG_printf("1cupsCreateCredentials: Unable to import public key: %s", gnutls_strerror(err));
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(err), 0);
+ goto done;
+ }
+ else if ((err = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0)
+ {
+ DEBUG_printf("1cupsCreateCredentials: Unable to export public key: %s", gnutls_strerror(err));
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(err), 0);
+ goto done;
+ }
+ else if ((fp = cupsFileOpen(pubfile, "w")) != NULL)
+ {
+ DEBUG_printf("1cupsCreateCredentials: Writing public key to \"%s\".", keyfile);
+ cupsFileWrite(fp, (char *)buffer, bytes);
+ cupsFileClose(fp);
+ }
+ else
+ {
+ DEBUG_printf("1cupsCreateCredentials: Unable to create public key file \"%s\": %s", keyfile, strerror(errno));
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
+ goto done;
+ }
+
+ // Create the certificate signing request...
DEBUG_puts("1cupsCreateCredentialsRequest: Generating X.509 certificate request.");
if (!organization)
if (purpose & CUPS_CREDPURPOSE_OCSP_SIGNING)
gnutls_x509_crq_set_key_purpose_oid(crq, GNUTLS_KP_OCSP_SIGNING, 0);
- if (usage & CUPS_CREDUSAGE_DIGITAL_SIGNATURE)
- gnutls_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE;
- if (usage & CUPS_CREDUSAGE_NON_REPUDIATION)
- gnutls_usage |= GNUTLS_KEY_NON_REPUDIATION;
- if (usage & CUPS_CREDUSAGE_KEY_ENCIPHERMENT)
- gnutls_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
- if (usage & CUPS_CREDUSAGE_DATA_ENCIPHERMENT)
- gnutls_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
- if (usage & CUPS_CREDUSAGE_KEY_AGREEMENT)
- gnutls_usage |= GNUTLS_KEY_KEY_AGREEMENT;
- if (usage & CUPS_CREDUSAGE_KEY_CERT_SIGN)
- gnutls_usage |= GNUTLS_KEY_KEY_CERT_SIGN;
- if (usage & CUPS_CREDUSAGE_CRL_SIGN)
- gnutls_usage |= GNUTLS_KEY_CRL_SIGN;
- if (usage & CUPS_CREDUSAGE_ENCIPHER_ONLY)
- gnutls_usage |= GNUTLS_KEY_ENCIPHER_ONLY;
- if (usage & CUPS_CREDUSAGE_DECIPHER_ONLY)
- gnutls_usage |= GNUTLS_KEY_DECIPHER_ONLY;
-
gnutls_x509_crq_set_key_usage(crq, gnutls_usage);
gnutls_x509_crq_set_version(crq, 3);
gnutls_x509_crq_deinit(crq);
if (key)
gnutls_x509_privkey_deinit(key);
+ if (pubkey)
+ gnutls_pubkey_deinit(pubkey);
return (ret);
}
char defpath[1024], // Default path
crtfile[1024], // Certificate filename
keyfile[1024], // Private key filename
+ pubfile[1024], // Public key filename
root_crtfile[1024], // Root certificate filename
root_keyfile[1024]; // Root private key filename
time_t curtime; // Current time
X509_set_notBefore(cert, notBefore);
ASN1_TIME_free(notBefore);
- notAfter = ASN1_TIME_new();
+ notAfter = ASN1_TIME_new();
ASN1_TIME_set(notAfter, expiration_date);
X509_set_notAfter(cert, notAfter);
ASN1_TIME_free(notAfter);
// Save them...
http_make_path(crtfile, sizeof(crtfile), path, common_name, "crt");
http_make_path(keyfile, sizeof(keyfile), path, common_name, "key");
+ http_make_path(pubfile, sizeof(pubfile), path, common_name, "pub");
if ((bio = BIO_new_file(keyfile, "wb")) == NULL)
{
BIO_free(bio);
+ if ((bio = BIO_new_file(pubfile, "wb")) == NULL)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
+ goto done;
+ }
+
+ if (!PEM_write_bio_PUBKEY(bio, pkey))
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to write public key."), true);
+ BIO_free(bio);
+ goto done;
+ }
+
+ BIO_free(bio);
+
if ((bio = BIO_new_file(crtfile, "wb")) == NULL)
{
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
char temp[1024], // Temporary directory name
*tempptr, // Pointer into temporary string
csrfile[1024], // Certificate signing request filename
- keyfile[1024]; // Private key filename
+ keyfile[1024], // Private key filename
+ pubfile[1024]; // Public key filename
STACK_OF(X509_EXTENSION) *exts; // Extensions
unsigned i; // Looping var
cups_credpurpose_t purpose_bit; // Current purpose
http_make_path(csrfile, sizeof(csrfile), path, common_name, "csr");
http_make_path(keyfile, sizeof(keyfile), path, common_name, "ktm");
+ http_make_path(pubfile, sizeof(pubfile), path, common_name, "pub");
// Create the encryption key...
DEBUG_puts("1cupsCreateCredentialsRequest: Creating key pair.");
BIO_free(bio);
+ if ((bio = BIO_new_file(pubfile, "wb")) == NULL)
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
+ goto done;
+ }
+
+ if (!PEM_write_bio_PUBKEY(bio, pkey))
+ {
+ _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to write public key."), true);
+ BIO_free(bio);
+ goto done;
+ }
+
+ BIO_free(bio);
+
if ((bio = BIO_new_file(csrfile, "wb")) == NULL)
{
_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
ASN1_INTEGER *serial; // Serial number
ASN1_TIME *notBefore, // Initial date
*notAfter; // Expiration date
- BIO *bio; // Output file
+ BIO *bio; // Input/output file
char temp[1024]; // Temporary string
int i, j, // Looping vars
num_exts; // Number of extensions