예제 #1
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);
}
예제 #2
0
int
pk_genkeypair(int argc, char *argv[])
{
	int rv;
	int opt;
	extern int	optind_av;
	extern char	*optarg_av;
	KMF_KEYSTORE_TYPE kstype = 0;
	char *tokenname = NULL;
	char *dir = NULL;
	char *prefix = NULL;
	char *keytype = PK_DEFAULT_KEYTYPE;
	int keylen = PK_DEFAULT_KEYLENGTH;
	char *label = NULL;
	char *outkey = NULL;
	char *format = NULL;
	KMF_HANDLE_T kmfhandle = NULL;
	KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
	KMF_KEY_ALG keyAlg = KMF_RSA;
	KMF_ALGORITHM_INDEX sigAlg;
	KMF_CREDENTIAL tokencred = {NULL, 0};
	KMF_OID *curveoid = NULL; /* ECC */
	int y_flag = 0;

	while ((opt = getopt_av(argc, argv,
	    "k:(keystore)s:(subject)n:(nickname)"
	    "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)"
	    "l:(label)K:(outkey)F:(format)C:(curve)"
	    "E(listcurves)")) != EOF) {

		if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av))
			return (PK_ERR_USAGE);

		switch (opt) {
			case 'k':
				kstype = KS2Int(optarg_av);
				if (kstype == 0)
					return (PK_ERR_USAGE);
				break;
			case 'l':
			case 'n':
				if (label)
					return (PK_ERR_USAGE);
				label = optarg_av;
				break;
			case 'T':
				if (tokenname)
					return (PK_ERR_USAGE);
				tokenname = optarg_av;
				break;
			case 'd':
				if (dir)
					return (PK_ERR_USAGE);
				dir = optarg_av;
				break;
			case 'p':
				if (prefix)
					return (PK_ERR_USAGE);
				prefix = optarg_av;
				break;
			case 't':
				keytype = optarg_av;
				break;
			case 'y':
				if (sscanf(optarg_av, "%d",
				    &keylen) != 1) {
					cryptoerror(LOG_STDERR,
					    gettext("key length must be"
					    "a numeric value (%s)\n"),
					    optarg_av);
					return (PK_ERR_USAGE);
				}
				y_flag++;
				break;
			case 'K':
				if (outkey)
					return (PK_ERR_USAGE);
				outkey = optarg_av;
				break;
			case 'F':
				if (format)
					return (PK_ERR_USAGE);
				format = optarg_av;
				break;
			case 'C':
				curveoid = ecc_name_to_oid(optarg_av);
				if (curveoid == NULL) {
					cryptoerror(LOG_STDERR,
					    gettext(
					    "Unrecognized ECC curve.\n"));
					return (PK_ERR_USAGE);
				}
				break;
			case 'E':
				show_ecc_curves();
				return (0);
			default:
				return (PK_ERR_USAGE);
		}
	}

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

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

	/* Assume keystore = PKCS#11 if not specified. */
	if (kstype == 0)
		kstype = KMF_KEYSTORE_PK11TOKEN;

	DIR_OPTION_CHECK(kstype, dir);

	if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
		cryptoerror(LOG_STDERR,
		    gettext("Error parsing format string (%s).\n"),
		    format);
		return (PK_ERR_USAGE);
	}

	if (Str2KeyType(keytype, NULL, &keyAlg, &sigAlg) != 0) {
		cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"),
		    keytype);
		return (PK_ERR_USAGE);
	}
	if (curveoid != NULL && keyAlg != KMF_ECDSA) {
		cryptoerror(LOG_STDERR, gettext("EC curves are only "
		    "valid for EC keytypes.\n"));
		return (PK_ERR_USAGE);
	}
	if (keyAlg == KMF_ECDSA && curveoid == NULL) {
		cryptoerror(LOG_STDERR, gettext("A curve must be "
		    "specifed when using EC keys.\n"));
		return (PK_ERR_USAGE);
	}
	if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
		(void) fprintf(stderr, gettext("ECC certificates are"
		    "only supported with the pkcs11 and nss keystores\n"));
		rv = PK_ERR_USAGE;
		goto end;
	}
	/* Adjust default keylength for NSS and DSA */
	if (keyAlg == KMF_DSA && kstype == KMF_KEYSTORE_NSS) {
		/* NSS only allows for 512-1024 bit DSA keys */
		if (!y_flag)
			/* If nothing was given, default to 1024 */
			keylen = 1024;
		else if (keylen > 1024 || keylen < 512) {
			(void) fprintf(stderr, gettext("NSS keystore only "
			    "supports DSA keylengths of 512 - 1024 bits\n"));
			rv = PK_ERR_USAGE;
			goto end;
		}
	}

	if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
		if (label == NULL) {
			(void) fprintf(stderr,
			    gettext("No key label specified\n"));
			rv = PK_ERR_USAGE;
			goto end;
		}
		if (tokenname == NULL || !strlen(tokenname)) {
			if (kstype == KMF_KEYSTORE_NSS) {
				tokenname = "internal";
			} else  {
				tokenname = PK_DEFAULT_PK11TOKEN;
			}
		}

		(void) get_token_password(kstype, tokenname, &tokencred);
	}

	if (kstype == KMF_KEYSTORE_NSS) {
		if (dir == NULL)
			dir = PK_DEFAULT_DIRECTORY;

		rv = genkeypair_nss(kmfhandle,
		    tokenname, label, dir, prefix, keyAlg, keylen,
		    &tokencred, curveoid, NULL, NULL);

	} else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
		rv = genkeypair_pkcs11(kmfhandle,
		    tokenname, label, keyAlg, keylen,
		    &tokencred, curveoid, NULL, NULL);

	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
		rv = genkeypair_file(kmfhandle, keyAlg, keylen,
		    fmt, outkey, NULL, NULL);
	}

	if (rv != KMF_OK)
		display_error(kmfhandle, rv,
		    gettext("Error creating and keypair"));
end:
	if (tokencred.cred != NULL)
		free(tokencred.cred);

	(void) kmf_finalize(kmfhandle);
	return (rv);
}
예제 #3
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);
}