Exemple #1
0
static KMF_RETURN
gencsr_pkcs11(KMF_HANDLE_T kmfhandle,
	char *token, char *subject, char *altname,
	KMF_GENERALNAMECHOICES alttype, int altcrit,
	char *certlabel, KMF_KEY_ALG keyAlg,
	int keylen, uint16_t kubits, int kucrit,
	KMF_ENCODE_FORMAT fmt, char *csrfile,
	KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist,
	KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid)
{
	KMF_RETURN kmfrv = KMF_OK;
	KMF_KEY_HANDLE pubk, prik;
	KMF_X509_NAME	csrSubject;
	KMF_CSR_DATA	csr;
	KMF_DATA signedCsr = {NULL, 0};

	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
	int numattr = 0;
	KMF_ATTRIBUTE attrlist[16];

	(void) memset(&csr, 0, sizeof (csr));
	(void) memset(&csrSubject, 0, sizeof (csrSubject));

	/* If the subject name cannot be parsed, flag it now and exit */
	if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK)
		return (kmfrv);

	/* Select a PKCS11 token */
	kmfrv = select_token(kmfhandle, token, FALSE);
	if (kmfrv != KMF_OK)
		return (kmfrv);
	/*
	 * Share the "genkeypair" routine for creating the keypair.
	 */
	kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel,
	    keyAlg, keylen, tokencred, curveoid, &prik, &pubk);
	if (kmfrv != KMF_OK)
		return (kmfrv);

	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair");

	SET_VALUE(kmf_set_csr_version(&csr, 2), "version number");

	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name");

	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg),
	    "SignatureAlgorithm");

	if (altname != NULL) {
		SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
		    alttype), "SetCSRSubjectAltName");
	}

	if (kubits != 0) {
		SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
		    "SetCSRKeyUsage");
	}
	if (ekulist != NULL) {
		int i;
		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
			SET_VALUE(kmf_add_csr_eku(&csr,
			    &ekulist->ekulist[i],
			    ekulist->critlist[i]),
			    "Extended Key Usage");
		}
	}
	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
	    KMF_OK) {
		kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
	}

cleanup:
	(void) kmf_free_data(&signedCsr);
	(void) kmf_free_signed_csr(&csr);

	/* delete the public key */
	numattr = 0;
	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
	    &kstype, sizeof (kstype));
	numattr++;

	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
	    &pubk, sizeof (KMF_KEY_HANDLE));
	numattr++;

	if (tokencred != NULL && tokencred->cred != NULL) {
		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
		    tokencred, sizeof (KMF_CREDENTIAL));
		numattr++;
	}

	(void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);

	/*
	 * If there is an error, then we need to remove the private key
	 * from the token.
	 */
	if (kmfrv != KMF_OK) {
		numattr = 0;
		kmf_set_attr_at_index(attrlist, numattr,
		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
		numattr++;

		kmf_set_attr_at_index(attrlist, numattr,
		    KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
		numattr++;

		if (tokencred != NULL && tokencred->cred != NULL) {
			kmf_set_attr_at_index(attrlist, numattr,
			    KMF_CREDENTIAL_ATTR, tokencred,
			    sizeof (KMF_CREDENTIAL));
			numattr++;
		}

		(void) kmf_delete_key_from_keystore(kmfhandle, numattr,
		    attrlist);
	}

	(void) kmf_free_kmf_key(kmfhandle, &prik);
	return (kmfrv);
}
Exemple #2
0
static KMF_RETURN
gencsr_file(KMF_HANDLE_T kmfhandle,
	KMF_KEY_ALG keyAlg,
	int keylen, KMF_ENCODE_FORMAT fmt,
	char *subject, char *altname, KMF_GENERALNAMECHOICES alttype,
	int altcrit, uint16_t kubits, int kucrit,
	char *outcsr, char *outkey, EKU_LIST *ekulist,
	KMF_ALGORITHM_INDEX sigAlg)
{
	KMF_RETURN kmfrv;
	KMF_KEY_HANDLE pubk, prik;
	KMF_X509_NAME	csrSubject;
	KMF_CSR_DATA	csr;
	KMF_DATA signedCsr = {NULL, 0};
	char *fullcsrpath = NULL;
	char *fullkeypath = NULL;


	(void) memset(&csr, 0, sizeof (csr));
	(void) memset(&csrSubject, 0, sizeof (csrSubject));

	if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) {
		cryptoerror(LOG_STDERR,
		    gettext("No output file was specified for "
		    "the csr or key\n"));
		return (KMF_ERR_BAD_PARAMETER);
	}
	fullcsrpath = strdup(outcsr);
	if (verify_file(fullcsrpath)) {
		cryptoerror(LOG_STDERR,
		    gettext("Cannot write the indicated output "
		    "certificate file (%s).\n"), fullcsrpath);
		free(fullcsrpath);
		return (PK_ERR_USAGE);
	}

	/* If the subject name cannot be parsed, flag it now and exit */
	if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
		return (kmfrv);
	}
	/*
	 * Share the "genkeypair" routine for creating the keypair.
	 */
	kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen,
	    fmt, outkey, &prik, &pubk);
	if (kmfrv != KMF_OK)
		return (kmfrv);

	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
	    "SetCSRPubKey");

	SET_VALUE(kmf_set_csr_version(&csr, 2), "SetCSRVersion");

	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
	    "kmf_set_csr_subject");

	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");

	if (altname != NULL) {
		SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
		    alttype), "kmf_set_csr_subject_altname");
	}
	if (kubits != NULL) {
		SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
		    "kmf_set_csr_ku");
	}
	if (ekulist != NULL) {
		int i;
		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
			SET_VALUE(kmf_add_csr_eku(&csr,
			    &ekulist->ekulist[i],
			    ekulist->critlist[i]),
			    "Extended Key Usage");
		}
	}
	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
	    KMF_OK) {
		kmfrv = kmf_create_csr_file(&signedCsr, fmt, fullcsrpath);
	}

cleanup:
	if (fullkeypath)
		free(fullkeypath);
	if (fullcsrpath)
		free(fullcsrpath);

	kmf_free_data(&signedCsr);
	kmf_free_kmf_key(kmfhandle, &prik);
	kmf_free_signed_csr(&csr);

	return (kmfrv);
}
Exemple #3
0
static KMF_RETURN
gencsr_nss(KMF_HANDLE_T kmfhandle,
	char *token, char *subject, char *altname,
	KMF_GENERALNAMECHOICES alttype, int altcrit,
	char *nickname, char *dir, char *prefix,
	KMF_KEY_ALG keyAlg, int keylen,
	uint16_t kubits, int kucrit,
	KMF_ENCODE_FORMAT fmt, char *csrfile,
	KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist,
	KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid)
{
	KMF_RETURN kmfrv;
	KMF_KEY_HANDLE pubk, prik;
	KMF_X509_NAME	csrSubject;
	KMF_CSR_DATA	csr;
	KMF_DATA signedCsr = {NULL, 0};

	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
	int numattr = 0;
	KMF_ATTRIBUTE attrlist[16];

	if (token == NULL)
		token = DEFAULT_NSS_TOKEN;

	kmfrv = configure_nss(kmfhandle, dir, prefix);
	if (kmfrv != KMF_OK)
		return (kmfrv);

	(void) memset(&csr, 0, sizeof (csr));
	(void) memset(&csrSubject, 0, sizeof (csrSubject));
	(void) memset(&pubk, 0, sizeof (pubk));
	(void) memset(&prik, 0, sizeof (prik));

	/* If the subject name cannot be parsed, flag it now and exit */
	if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) {
		return (kmfrv);
	}

	kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
	    prefix, keyAlg, keylen, tokencred, curveoid,
	    &prik, &pubk);
	if (kmfrv != KMF_OK)
		return (kmfrv);

	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr),
	    "kmf_set_csr_pubkey");
	SET_VALUE(kmf_set_csr_version(&csr, 2), "kmf_set_csr_version");
	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject),
	    "kmf_set_csr_subject");
	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg");

	if (altname != NULL) {
		SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit,
		    alttype), "kmf_set_csr_subject_altname");
	}
	if (kubits != NULL) {
		SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits),
		    "kmf_set_csr_ku");
	}
	if (ekulist != NULL) {
		int i;
		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
			SET_VALUE(kmf_add_csr_eku(&csr,
			    &ekulist->ekulist[i],
			    ekulist->critlist[i]),
			    "Extended Key Usage");
		}
	}
	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
	    KMF_OK) {
		kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile);
	}

cleanup:
	(void) kmf_free_data(&signedCsr);
	(void) kmf_free_kmf_key(kmfhandle, &prik);

	/* delete the key */
	numattr = 0;
	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
	    &kstype, sizeof (kstype));
	numattr++;

	kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR,
	    &pubk, sizeof (KMF_KEY_HANDLE));
	numattr++;

	if (tokencred != NULL && tokencred->credlen > 0) {
		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
		    tokencred, sizeof (KMF_CREDENTIAL));
		numattr++;
	}

	if (token && strlen(token)) {
		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
		    token, strlen(token));
		numattr++;
	}

	(void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist);

	(void) kmf_free_signed_csr(&csr);

	return (kmfrv);
}
Exemple #4
0
static int
gencert_pkcs11(KMF_HANDLE_T kmfhandle,
	char *token, char *subject, char *altname,
	KMF_GENERALNAMECHOICES alttype, int altcrit,
	char *certlabel, KMF_KEY_ALG keyAlg,
	KMF_ALGORITHM_INDEX sigAlg,
	int keylen, uint32_t ltime, KMF_BIGINT *serial,
	uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred,
	EKU_LIST *ekulist, KMF_OID *curveoid)
{
	KMF_RETURN kmfrv = KMF_OK;
	KMF_KEY_HANDLE pubk, prik;
	KMF_X509_CERTIFICATE signedCert;
	KMF_X509_NAME	certSubject;
	KMF_X509_NAME	certIssuer;
	KMF_DATA x509DER;
	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
	KMF_ATTRIBUTE attrlist[16];
	int numattr = 0;
	KMF_KEY_ALG keytype;
	uint32_t keylength;

	(void) memset(&signedCert, 0, sizeof (signedCert));
	(void) memset(&certSubject, 0, sizeof (certSubject));
	(void) memset(&certIssuer, 0, sizeof (certIssuer));
	(void) memset(&x509DER, 0, sizeof (x509DER));

	/* If the subject name cannot be parsed, flag it now and exit */
	if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Subject name cannot be parsed.\n"));
		return (PK_ERR_USAGE);
	}

	/* For a self-signed cert, the issuser and subject are the same */
	if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Subject name cannot be parsed.\n"));
		return (PK_ERR_USAGE);
	}

	keylength = keylen; /* bits */
	keytype = keyAlg;

	/* Select a PKCS11 token */
	kmfrv = select_token(kmfhandle, token, FALSE);
	if (kmfrv != KMF_OK) {
		return (kmfrv);
	}

	/*
	 * Share the "genkeypair" routine for creating the keypair.
	 */
	kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel,
	    keytype, keylength, tokencred, curveoid, &prik, &pubk);
	if (kmfrv != KMF_OK)
		return (kmfrv);

	SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
	    "keypair");

	SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");

	SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
	    "serial number");

	SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime),
	    "validity time");

	SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
	    "signature algorithm");

	SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
	    "subject name");

	SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
	    "issuer name");

	if (altname != NULL)
		SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
		    alttype, altname), "subjectAltName");

	if (kubits != 0)
		SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
		    "KeyUsage");

	if (ekulist != NULL) {
		int i;
		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
			SET_VALUE(kmf_add_cert_eku(&signedCert,
			    &ekulist->ekulist[i], ekulist->critlist[i]),
			    "Extended Key Usage");
		}
	}

	/*
	 * Construct attributes for the kmf_sign_cert operation.
	 */
	numattr = 0;
	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
	    &kstype, sizeof (kstype));
	numattr++;

	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
	    &prik, sizeof (KMF_KEY_HANDLE_ATTR));
	numattr++;

	/* cert data that is to be signed */
	kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
	    &signedCert, sizeof (KMF_X509_CERTIFICATE));
	numattr++;

	/* output buffer for the signed cert */
	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
	    &x509DER, sizeof (KMF_DATA));
	numattr++;

	kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
	    &sigAlg, sizeof (sigAlg));
	numattr++;

	if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
	    KMF_OK) {
		goto cleanup;
	}

	/*
	 * Store the cert in the DB.
	 */
	numattr = 0;
	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
	    &kstype, sizeof (kstype));
	numattr++;
	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
	    &x509DER, sizeof (KMF_DATA));
	numattr++;

	if (certlabel != NULL) {
		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
		    certlabel, strlen(certlabel));
		numattr++;
	}

	kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);

cleanup:
	kmf_free_data(&x509DER);
	kmf_free_dn(&certSubject);
	kmf_free_dn(&certIssuer);

	/*
	 * If kmf_sign_cert or kmf_store_cert failed, then we need to clean up
	 * the key pair from the token.
	 */
	if (kmfrv != KMF_OK) {
		/* delete the public key */
		numattr = 0;
		kmf_set_attr_at_index(attrlist, numattr,
		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
		numattr++;

		kmf_set_attr_at_index(attrlist, numattr,
		    KMF_KEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE));
		numattr++;

		if (tokencred != NULL && tokencred->cred != NULL) {
			kmf_set_attr_at_index(attrlist, numattr,
			    KMF_CREDENTIAL_ATTR, tokencred,
			    sizeof (KMF_CREDENTIAL));
			numattr++;
		}

		(void) kmf_delete_key_from_keystore(kmfhandle, numattr,
		    attrlist);

		/* delete the private key */
		numattr = 0;
		kmf_set_attr_at_index(attrlist, numattr,
		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
		numattr++;

		kmf_set_attr_at_index(attrlist, numattr,
		    KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
		numattr++;

		if (tokencred != NULL && tokencred->cred != NULL) {
			kmf_set_attr_at_index(attrlist, numattr,
			    KMF_CREDENTIAL_ATTR, tokencred,
			    sizeof (KMF_CREDENTIAL));
			numattr++;
		}

		(void) kmf_delete_key_from_keystore(kmfhandle, numattr,
		    attrlist);
	}

	return (kmfrv);
}
Exemple #5
0
static KMF_RETURN
gencert_nss(KMF_HANDLE_T kmfhandle,
	char *token, char *subject, char *altname,
	KMF_GENERALNAMECHOICES alttype, int altcrit,
	char *nickname, char *dir, char *prefix,
	KMF_KEY_ALG keyAlg,
	KMF_ALGORITHM_INDEX sigAlg,
	int keylen, char *trust,
	uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits,
	int kucrit, KMF_CREDENTIAL *tokencred,
	EKU_LIST *ekulist, KMF_OID *curveoid)
{
	KMF_RETURN kmfrv;
	KMF_KEY_HANDLE pubk, prik;
	KMF_X509_CERTIFICATE signedCert;
	KMF_X509_NAME	certSubject;
	KMF_X509_NAME	certIssuer;
	KMF_DATA x509DER;
	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
	KMF_ATTRIBUTE attrlist[16];
	int numattr = 0;

	if (token == NULL)
		token = DEFAULT_NSS_TOKEN;

	kmfrv = configure_nss(kmfhandle, dir, prefix);
	if (kmfrv != KMF_OK)
		return (kmfrv);

	(void) memset(&signedCert, 0, sizeof (signedCert));
	(void) memset(&certSubject, 0, sizeof (certSubject));
	(void) memset(&certIssuer, 0, sizeof (certIssuer));
	(void) memset(&x509DER, 0, sizeof (x509DER));

	/* If the subject name cannot be parsed, flag it now and exit */
	if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Subject name cannot be parsed.\n"));
		return (PK_ERR_USAGE);
	}

	/* For a self-signed cert, the issuser and subject are the same */
	if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Subject name cannot be parsed.\n"));
		return (PK_ERR_USAGE);
	}

	kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
	    prefix, keyAlg, keylen, tokencred, curveoid,
	    &prik, &pubk);
	if (kmfrv != KMF_OK)
		return (kmfrv);

	SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
	    "keypair");

	SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");

	SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
	    "serial number");

	SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime),
	    "validity time");

	SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
	    "signature algorithm");

	SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
	    "subject name");

	SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
	    "issuer name");

	if (altname != NULL)
		SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
		    alttype, altname), "subjectAltName");

	if (kubits)
		SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
		    "subjectAltName");

	if (ekulist != NULL) {
		int i;
		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
			SET_VALUE(kmf_add_cert_eku(&signedCert,
			    &ekulist->ekulist[i],
			    ekulist->critlist[i]), "Extended Key Usage");
		}
	}
	/*
	 * Construct attributes for the kmf_sign_cert operation.
	 */
	numattr = 0;
	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
	    &kstype, sizeof (kstype));
	numattr++;

	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
	    &prik, sizeof (KMF_KEY_HANDLE_ATTR));
	numattr++;

	/* cert data that is to be signed */
	kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
	    &signedCert, sizeof (KMF_X509_CERTIFICATE));
	numattr++;

	/* output buffer for the signed cert */
	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
	    &x509DER, sizeof (KMF_DATA));
	numattr++;

	kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
	    &sigAlg, sizeof (sigAlg));
	numattr++;

	if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
	    KMF_OK) {
		goto cleanup;
	}

	/*
	 * Store the cert in the DB.
	 */
	numattr = 0;
	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
	    &kstype, sizeof (kstype));
	numattr++;

	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
	    &x509DER, sizeof (KMF_DATA));
	numattr++;

	if (nickname != NULL) {
		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
		    nickname, strlen(nickname));
		numattr++;
	}

	if (trust != NULL) {
		kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR,
		    trust, strlen(trust));
		numattr++;
	}

	if (token != NULL) {
		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
		    token, strlen(token));
		numattr++;
	}

	kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);

cleanup:
	kmf_free_data(&x509DER);
	kmf_free_dn(&certSubject);
	kmf_free_dn(&certIssuer);
	return (kmfrv);
}
Exemple #6
0
static int
gencert_file(KMF_HANDLE_T kmfhandle,
	KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg,
	int keylen, KMF_ENCODE_FORMAT fmt,
	uint32_t ltime, char *subject, char *altname,
	KMF_GENERALNAMECHOICES alttype, int altcrit,
	KMF_BIGINT *serial, uint16_t kubits, int kucrit,
	char *outcert, char *outkey,
	EKU_LIST *ekulist)
{
	KMF_RETURN kmfrv;
	KMF_KEY_HANDLE pubk, prik;
	KMF_X509_CERTIFICATE signedCert;
	KMF_X509_NAME	certSubject;
	KMF_X509_NAME	certIssuer;
	KMF_DATA x509DER;
	char *fullcertpath = NULL;
	char *fullkeypath = NULL;
	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
	KMF_ATTRIBUTE attrlist[10];
	int numattr = 0;

	(void) memset(&signedCert, 0, sizeof (signedCert));
	(void) memset(&certSubject, 0, sizeof (certSubject));
	(void) memset(&certIssuer, 0, sizeof (certIssuer));
	(void) memset(&x509DER, 0, sizeof (x509DER));

	if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) {
		cryptoerror(LOG_STDERR,
		    gettext("No output file was specified for "
		    "the cert or key\n"));
		return (PK_ERR_USAGE);
	}
	fullcertpath = strdup(outcert);
	if (verify_file(fullcertpath)) {
		cryptoerror(LOG_STDERR,
		    gettext("Cannot write the indicated output "
		    "certificate file (%s).\n"), fullcertpath);
		free(fullcertpath);
		return (PK_ERR_USAGE);
	}

	/* If the subject name cannot be parsed, flag it now and exit */
	if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Subject name cannot be parsed (%s)\n"), subject);
		return (PK_ERR_USAGE);
	}

	/* For a self-signed cert, the issuser and subject are the same */
	if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Subject name cannot be parsed (%s)\n"), subject);
		kmf_free_dn(&certSubject);
		return (PK_ERR_USAGE);
	}

	/*
	 * Share the "genkeypair" routine for creating the keypair.
	 */
	kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen,
	    fmt, outkey, &prik, &pubk);
	if (kmfrv != KMF_OK)
		return (kmfrv);

	SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
	    "keypair");

	SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");

	SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
	    "serial number");

	SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime),
	    "validity time");

	SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
	    "signature algorithm");

	SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
	    "subject name");

	SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
	    "issuer name");

	if (altname != NULL)
		SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
		    alttype, altname), "subjectAltName");

	if (kubits != 0)
		SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
		    "KeyUsage");

	if (ekulist != NULL) {
		int i;
		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
			SET_VALUE(kmf_add_cert_eku(&signedCert,
			    &ekulist->ekulist[i],
			    ekulist->critlist[i]), "Extended Key Usage");
		}
	}
	/*
	 * Construct attributes for the kmf_sign_cert operation.
	 */
	numattr = 0;
	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
	    &kstype, sizeof (kstype));
	numattr++;

	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
	    &prik, sizeof (KMF_KEY_HANDLE_ATTR));
	numattr++;

	/* cert data that is to be signed */
	kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
	    &signedCert, sizeof (KMF_X509_CERTIFICATE));
	numattr++;

	/* output buffer for the signed cert */
	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
	    &x509DER, sizeof (KMF_DATA));
	numattr++;

	kmf_set_attr_at_index(attrlist, numattr, KMF_ALGORITHM_INDEX_ATTR,
	    &sigAlg, sizeof (sigAlg));
	numattr++;

	if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
	    KMF_OK) {
		goto cleanup;
	}

	/*
	 * Store the cert in the DB.
	 */
	numattr = 0;
	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
	    &kstype, sizeof (kstype));
	numattr++;
	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
	    &x509DER, sizeof (KMF_DATA));
	numattr++;
	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR,
	    fullcertpath, strlen(fullcertpath));
	numattr++;
	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
	    &fmt, sizeof (fmt));
	numattr++;

	kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);

cleanup:
	if (fullkeypath != NULL)
		free(fullkeypath);
	if (fullcertpath != NULL)
		free(fullcertpath);

	kmf_free_data(&x509DER);
	kmf_free_dn(&certSubject);
	kmf_free_dn(&certIssuer);
	return (kmfrv);
}
Exemple #7
0
int
pk_download(int argc, char *argv[])
{
	int rv;
	int opt;
	extern int	optind_av;
	extern char	*optarg_av;
	int oclass = 0;
	char *url = NULL;
	char *http_proxy = NULL;
	char *dir = NULL;
	char *outfile = NULL;
	char *proxy = NULL;
	int  proxy_port = 0;
	KMF_HANDLE_T	kmfhandle = NULL;
	KMF_ENCODE_FORMAT format;
	KMF_RETURN ch_rv = KMF_OK;
	char *fullpath = NULL;
	KMF_DATA cert = { 0, NULL };
	KMF_DATA cert_der = { 0, NULL };

	while ((opt = getopt_av(argc, argv,
	    "t:(objtype)u:(url)h:(http_proxy)o:(outfile)d:(dir)")) != EOF) {

		if (EMPTYSTRING(optarg_av))
			return (PK_ERR_USAGE);
		switch (opt) {
		case 't':
			if (oclass)
				return (PK_ERR_USAGE);
			oclass = OT2Int(optarg_av);
			if (!(oclass & (PK_CERT_OBJ | PK_CRL_OBJ)))
				return (PK_ERR_USAGE);
			break;
		case 'u':
			if (url)
				return (PK_ERR_USAGE);
			url = optarg_av;
			break;
		case 'h':
			if (http_proxy)
				return (PK_ERR_USAGE);
			http_proxy = optarg_av;
			break;
		case 'o':
			if (outfile)
				return (PK_ERR_USAGE);
			outfile = optarg_av;
			break;
		case 'd':
			if (dir)
				return (PK_ERR_USAGE);
			dir = optarg_av;
			break;
		default:
			cryptoerror(LOG_STDERR, gettext(
			    "unrecognized download option '%s'\n"),
			    argv[optind_av]);
			return (PK_ERR_USAGE);
		}
	}

	/* No additional args allowed. */
	argc -= optind_av;
	argv += optind_av;
	if (argc) {
		return (PK_ERR_USAGE);
	}

	/* Check the dir and outfile options */
	if (outfile == NULL) {
		/* If outfile is not specified, use the basename of URI */
		outfile = basename(url);
	}

	fullpath = get_fullpath(dir, outfile);
	if (fullpath == NULL) {
		cryptoerror(LOG_STDERR, gettext("Incorrect dir or outfile "
		    "option value \n"));
		return (PK_ERR_USAGE);
	}
	/* Check if the file exists and might be overwritten. */
	if (verify_file(fullpath) != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Warning: file \"%s\" exists, "
		    "will be overwritten."), fullpath);
		if (yesno(gettext("Continue with download? "),
		    gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
			return (0);
		}
	}
	/* URI MUST be specified */
	if (url == NULL) {
		cryptoerror(LOG_STDERR, gettext("A URL must be specified\n"));
		rv = PK_ERR_USAGE;
		goto end;
	}

	/*
	 * Get the http proxy from the command "http_proxy" option or the
	 * environment variable.  The command option has a higher priority.
	 */
	if (http_proxy == NULL)
		http_proxy = getenv("http_proxy");

	if (http_proxy != NULL) {
		char *ptmp = http_proxy;
		char *proxy_port_s;

		if (strncasecmp(ptmp, "http://", 7) == 0)
			ptmp += 7;	/* skip the scheme prefix */

		proxy = strtok(ptmp, ":");
		proxy_port_s = strtok(NULL, "\0");
		if (proxy_port_s != NULL)
			proxy_port = strtol(proxy_port_s, NULL, 0);
		else
			proxy_port = 8080;
	}

	/* If objtype is not specified, default to CRL */
	if (oclass == 0) {
		oclass = PK_CRL_OBJ;
	}

	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
		rv = PK_ERR_USAGE;
		goto end;
	}

	/* Now we are ready to download */
	if (oclass & PK_CRL_OBJ) {
		rv = kmf_download_crl(kmfhandle, url, proxy, proxy_port, 30,
		    fullpath, &format);
	} else if (oclass & PK_CERT_OBJ) {
		rv = kmf_download_cert(kmfhandle, url, proxy, proxy_port, 30,
		    fullpath, &format);
	}

	if (rv != KMF_OK) {
		switch (rv) {
		case KMF_ERR_BAD_URI:
			cryptoerror(LOG_STDERR,
			    gettext("Error in parsing URI\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_OPEN_FILE:
			cryptoerror(LOG_STDERR,
			    gettext("Error in opening file\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_WRITE_FILE:
			cryptoerror(LOG_STDERR,
			    gettext("Error in writing file\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_BAD_CRLFILE:
			cryptoerror(LOG_STDERR, gettext("Not a CRL file\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_BAD_CERTFILE:
			cryptoerror(LOG_STDERR,
			    gettext("Not a certificate file\n"));
			rv = PK_ERR_USAGE;
			break;
		case KMF_ERR_MEMORY:
			cryptoerror(LOG_STDERR,
			    gettext("Not enough memory\n"));
			rv = PK_ERR_SYSTEM;
			break;
		default:
			cryptoerror(LOG_STDERR,
			    gettext("Error in downloading the file.\n"));
			rv = PK_ERR_SYSTEM;
			break;
		}
		goto end;
	}

	/*
	 * If the file is successfully downloaded, we also check the date.
	 * If the downloaded file is outdated, give a warning.
	 */
	if (oclass & PK_CRL_OBJ) {
		ch_rv = kmf_check_crl_date(kmfhandle, fullpath);
	} else { /* certificate */
		ch_rv = kmf_read_input_file(kmfhandle, fullpath, &cert);
		if (ch_rv != KMF_OK)
			goto end;

		if (format == KMF_FORMAT_PEM) {
			int len;
			ch_rv = kmf_pem_to_der(cert.Data, cert.Length,
			    &cert_der.Data, &len);
			if (ch_rv != KMF_OK)
				goto end;
			cert_der.Length = (size_t)len;
		}

		ch_rv = kmf_check_cert_date(kmfhandle,
		    format == KMF_FORMAT_ASN1 ? &cert : &cert_der);
	}

end:
	if (ch_rv == KMF_ERR_VALIDITY_PERIOD) {
		cryptoerror(LOG_STDERR,
		    gettext("Warning: the downloaded file is expired.\n"));
	} else if (ch_rv != KMF_OK) {
		cryptoerror(LOG_STDERR,
		    gettext("Warning: failed to check the validity.\n"));
	}

	if (fullpath)
		free(fullpath);

	kmf_free_data(&cert);
	kmf_free_data(&cert_der);

	(void) kmf_finalize(kmfhandle);
	return (rv);
}
Exemple #8
0
/*
 * Convert an SPKI data record to PKCS#11
 * public key object.
 */
static KMF_RETURN
PKCS_CreatePublicKey(
	const KMF_X509_SPKI *pKey,
	CK_SESSION_HANDLE ckSession,
	CK_OBJECT_HANDLE *pckPublicKey)
{
	KMF_RETURN mrReturn = KMF_OK;
	CK_RV ckRv;

	CK_ATTRIBUTE ckTemplate[MAX_PUBLIC_KEY_TEMPLATES];
	CK_ULONG ckNumTemplates = 0;

	/* Common object attributes */
	CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY;
	CK_BBOOL ckToken = 0;
	CK_BBOOL ckPrivate = 0;

	/* Common key attributes */
	CK_KEY_TYPE ckKeyType;
	CK_BBOOL ckDerive = CK_FALSE;

	/* Common public key attributes */
	CK_BBOOL ckEncrypt = 1;
	CK_BBOOL ckVerify = 1;

	CK_BBOOL ckVerifyRecover = CK_FALSE;
	CK_BBOOL ckWrap = CK_FALSE;

	/* Key part array */
	KMF_DATA KeyParts[KMF_MAX_PUBLIC_KEY_PARTS];
	uint32_t i, uNumKeyParts = KMF_MAX_PUBLIC_KEY_PARTS;
	KMF_ALGORITHM_INDEX AlgorithmId;

	/* Parse the keyblob */
	(void) memset(KeyParts, 0, sizeof (KeyParts));

	AlgorithmId = x509_algoid_to_algid(
	    (KMF_OID *)&pKey->algorithm.algorithm);
	if (AlgorithmId == KMF_ALGID_NONE)
		return (KMF_ERR_BAD_ALGORITHM);

	mrReturn = ExtractSPKIData(pKey, AlgorithmId, KeyParts, &uNumKeyParts);

	if (mrReturn != KMF_OK)
		return (mrReturn);

	/* Fill in the common object attributes */
	if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    MAX_PUBLIC_KEY_TEMPLATES, CKA_CLASS, (CK_BYTE *)&ckObjClass,
	    sizeof (ckObjClass)) ||
	    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    MAX_PUBLIC_KEY_TEMPLATES, CKA_TOKEN, (CK_BYTE *)&ckToken,
	    sizeof (ckToken)) ||
	    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    MAX_PUBLIC_KEY_TEMPLATES, CKA_PRIVATE, (CK_BYTE *)&ckPrivate,
	    sizeof (ckPrivate))) {
		mrReturn = KMF_ERR_INTERNAL;
		goto cleanup;
	}

	/* Fill in the common key attributes */
	if (get_pk11_data(AlgorithmId, &ckKeyType, NULL, NULL, 0)) {
		goto cleanup;
	}
	if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    MAX_PUBLIC_KEY_TEMPLATES, CKA_KEY_TYPE, (CK_BYTE *)&ckKeyType,
	    sizeof (ckKeyType)) ||
	    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    MAX_PUBLIC_KEY_TEMPLATES, CKA_DERIVE, (CK_BYTE *)&ckDerive,
	    sizeof (ckDerive))) {
		mrReturn = KMF_ERR_INTERNAL;
		goto cleanup;
	}

	/* Add common public key attributes */
	if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    MAX_PUBLIC_KEY_TEMPLATES, CKA_ENCRYPT, (CK_BYTE *)&ckEncrypt,
	    sizeof (ckEncrypt)) ||
	    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    MAX_PUBLIC_KEY_TEMPLATES, CKA_VERIFY, (CK_BYTE *)&ckVerify,
	    sizeof (ckVerify)) ||
	    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    MAX_PUBLIC_KEY_TEMPLATES, CKA_VERIFY_RECOVER,
	    (CK_BYTE *)&ckVerifyRecover, sizeof (ckVerifyRecover)) ||
	    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
	    MAX_PUBLIC_KEY_TEMPLATES, CKA_WRAP, (CK_BYTE *)&ckWrap,
	    sizeof (ckWrap))) {
		mrReturn = KMF_ERR_INTERNAL;
		goto cleanup;
	}

	/* Add algorithm specific attributes */
	switch (ckKeyType) {
	case CKK_RSA:
		if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
		    MAX_PUBLIC_KEY_TEMPLATES, CKA_MODULUS,
		    (CK_BYTE *)KeyParts[KMF_RSA_MODULUS].Data,
		    (CK_ULONG)KeyParts[KMF_RSA_MODULUS].Length) ||

		    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
		    MAX_PUBLIC_KEY_TEMPLATES, CKA_PUBLIC_EXPONENT,
		    (CK_BYTE *)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Data,
		    (CK_ULONG)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Length)) {
			mrReturn = KMF_ERR_INTERNAL;
			goto cleanup;
		}
		break;
	case CKK_DSA:
		if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
		    MAX_PUBLIC_KEY_TEMPLATES, CKA_PRIME,
		    (CK_BYTE *)KeyParts[KMF_DSA_PRIME].Data,
		    (CK_ULONG)KeyParts[KMF_DSA_PRIME].Length) ||
		    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
		    MAX_PUBLIC_KEY_TEMPLATES, CKA_SUBPRIME,
		    (CK_BYTE *)KeyParts[KMF_DSA_SUB_PRIME].Data,
		    (CK_ULONG)KeyParts[KMF_DSA_SUB_PRIME].Length) ||
		    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
		    MAX_PUBLIC_KEY_TEMPLATES, CKA_BASE,
		    (CK_BYTE *)KeyParts[KMF_DSA_BASE].Data,
		    (CK_ULONG)KeyParts[KMF_DSA_BASE].Length) ||
		    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
		    MAX_PUBLIC_KEY_TEMPLATES, CKA_VALUE,
		    (CK_BYTE *)KeyParts[KMF_DSA_PUBLIC_VALUE].Data,
		    (CK_ULONG)KeyParts[KMF_DSA_PUBLIC_VALUE].Length)) {
		mrReturn = KMF_ERR_INTERNAL;
		goto cleanup;
		}
		break;
	case CKK_EC:
		if (!PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
		    MAX_PUBLIC_KEY_TEMPLATES, CKA_EC_POINT,
		    (CK_BYTE *)KeyParts[KMF_ECDSA_POINT].Data,
		    (CK_ULONG)KeyParts[KMF_ECDSA_POINT].Length) ||

		    !PKCS_AddTemplate(ckTemplate, &ckNumTemplates,
		    MAX_PUBLIC_KEY_TEMPLATES, CKA_EC_PARAMS,
		    (CK_BYTE *)KeyParts[KMF_ECDSA_PARAMS].Data,
		    (CK_ULONG)KeyParts[KMF_ECDSA_PARAMS].Length)) {
			mrReturn = KMF_ERR_INTERNAL;
			goto cleanup;
		}
		break;
	default:
		mrReturn = KMF_ERR_BAD_PARAMETER;
	}

	if (mrReturn == KMF_OK) {
		/* Instantiate the object */
		ckRv = C_CreateObject(ckSession, ckTemplate,
		    ckNumTemplates, pckPublicKey);
		if (ckRv != CKR_OK)
			mrReturn = KMF_ERR_INTERNAL;
	}

cleanup:
	for (i = 0; i < uNumKeyParts; i++) {
		kmf_free_data(&KeyParts[i]);
	}

	return (mrReturn);
}