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
int
kc_create(int argc, char *argv[])
{
    KMF_RETURN	ret;
    int 		rv = KC_OK;
    int		opt;
    extern int	optind_av;
    extern char	*optarg_av;
    char		*filename = NULL;
    int		ocsp_set_attr = 0;
    boolean_t	crl_set_attr = 0;
    KMF_POLICY_RECORD plc;

    (void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD));

    while ((opt = getopt_av(argc, argv,
                            "i:(dbfile)"
                            "p:(policy)"
                            "d:(ignore-date)"
                            "e:(ignore-unknown-eku)"
                            "a:(ignore-trust-anchor)"
                            "v:(validity-adjusttime)"
                            "t:(ta-name)"
                            "s:(ta-serial)"
                            "o:(ocsp-responder)"
                            "P:(ocsp-proxy)"
                            "r:(ocsp-use-cert-responder)"
                            "T:(ocsp-response-lifetime)"
                            "R:(ocsp-ignore-response-sign)"
                            "n:(ocsp-responder-cert-name)"
                            "A:(ocsp-responder-cert-serial)"
                            "c:(crl-basefilename)"
                            "I:(crl-directory)"
                            "g:(crl-get-crl-uri)"
                            "X:(crl-proxy)"
                            "S:(crl-ignore-crl-sign)"
                            "D:(crl-ignore-crl-date)"
                            "m:(mapper-name)"
                            "M:(mapper-directory)"
                            "Q:(mapper-pathname)"
                            "q:(mapper-options)"
                            "u:(keyusage)"
                            "E:(ekunames)"
                            "O:(ekuoids)")) != EOF) {
        switch (opt) {
        case 'i':
            filename = get_string(optarg_av, &rv);
            if (filename == NULL) {
                (void) fprintf(stderr,
                               gettext("Error dbfile input.\n"));
            }
            break;
        case 'p':
            plc.name = get_string(optarg_av, &rv);
            if (plc.name == NULL) {
                (void) fprintf(stderr,
                               gettext("Error policy name.\n"));
            }
            break;
        case 'd':
            plc.ignore_date = get_boolean(optarg_av);
            if (plc.ignore_date == -1) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
                rv = KC_ERR_USAGE;
            }
            break;
        case 'e':
            plc.ignore_unknown_ekus =
                get_boolean(optarg_av);
            if (plc.ignore_unknown_ekus == -1) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
                rv = KC_ERR_USAGE;
            }
            break;
        case 'a':
            plc.ignore_trust_anchor =
                get_boolean(optarg_av);
            if (plc.ignore_trust_anchor == -1) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
                rv = KC_ERR_USAGE;
            }
            break;
        case 'v':
            plc.validity_adjusttime =
                get_string(optarg_av, &rv);
            if (plc.validity_adjusttime == NULL) {
                (void) fprintf(stderr,
                               gettext("Error time input.\n"));
            } else {
                uint32_t adj;
                /* for syntax checking */
                if (str2lifetime(
                            plc.validity_adjusttime,
                            &adj) < 0) {
                    (void) fprintf(stderr,
                                   gettext("Error time "
                                           "input.\n"));
                    rv = KC_ERR_USAGE;
                }
            }
            break;
        case 't':
            plc.ta_name = get_string(optarg_av, &rv);
            if (plc.ta_name == NULL) {
                (void) fprintf(stderr,
                               gettext("Error name input.\n"));
            } else if (strcasecmp(plc.ta_name,
                                  "search") != 0) {
                KMF_X509_NAME taDN;
                /* for syntax checking */
                if (kmf_dn_parser(plc.ta_name,
                                  &taDN) != KMF_OK) {
                    (void) fprintf(stderr,
                                   gettext("Error name "
                                           "input.\n"));
                    rv = KC_ERR_USAGE;
                } else {
                    kmf_free_dn(&taDN);
                }
            }
            break;
        case 's':
            plc.ta_serial = get_string(optarg_av, &rv);
            if (plc.ta_serial == NULL) {
                (void) fprintf(stderr,
                               gettext("Error serial input.\n"));
            } else {
                uchar_t *bytes = NULL;
                size_t bytelen;

                ret = kmf_hexstr_to_bytes(
                          (uchar_t *)plc.ta_serial,
                          &bytes, &bytelen);
                if (ret != KMF_OK || bytes == NULL) {
                    (void) fprintf(stderr,
                                   gettext("serial number "
                                           "must be specified as a "
                                           "hex number "
                                           "(ex: 0x0102030405"
                                           "ffeeddee)\n"));
                    rv = KC_ERR_USAGE;
                }
                if (bytes != NULL)
                    free(bytes);
            }
            break;
        case 'o':
            plc.VAL_OCSP_RESPONDER_URI =
                get_string(optarg_av, &rv);
            if (plc.VAL_OCSP_RESPONDER_URI == NULL) {
                (void) fprintf(stderr, gettext(
                                   "Error responder input.\n"));
            } else {
                ocsp_set_attr++;
            }
            break;
        case 'P':
            plc.VAL_OCSP_PROXY =
                get_string(optarg_av, &rv);
            if (plc.VAL_OCSP_PROXY == NULL) {
                (void) fprintf(stderr,
                               gettext("Error proxy input.\n"));
            } else {
                ocsp_set_attr++;
            }
            break;
        case 'r':
            plc.VAL_OCSP_URI_FROM_CERT =
                get_boolean(optarg_av);
            if (plc.VAL_OCSP_URI_FROM_CERT == -1) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
                rv = KC_ERR_USAGE;
            } else {
                ocsp_set_attr++;
            }
            break;
        case 'T':
            plc.VAL_OCSP_RESP_LIFETIME =
                get_string(optarg_av, &rv);
            if (plc.VAL_OCSP_RESP_LIFETIME == NULL) {
                (void) fprintf(stderr,
                               gettext("Error time input.\n"));
            } else {
                uint32_t adj;
                /* for syntax checking */
                if (str2lifetime(
                            plc.VAL_OCSP_RESP_LIFETIME,
                            &adj) < 0) {
                    (void) fprintf(stderr,
                                   gettext("Error time "
                                           "input.\n"));
                    rv = KC_ERR_USAGE;
                } else {
                    ocsp_set_attr++;
                }
            }
            break;
        case 'R':
            plc.VAL_OCSP_IGNORE_RESP_SIGN =
                get_boolean(optarg_av);
            if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
                rv = KC_ERR_USAGE;
            } else {
                ocsp_set_attr++;
            }
            break;
        case 'n':
            plc.VAL_OCSP_RESP_CERT_NAME =
                get_string(optarg_av, &rv);
            if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) {
                (void) fprintf(stderr,
                               gettext("Error name input.\n"));
            } else {
                KMF_X509_NAME respDN;
                /* for syntax checking */
                if (kmf_dn_parser(
                            plc.VAL_OCSP_RESP_CERT_NAME,
                            &respDN) != KMF_OK) {
                    (void) fprintf(stderr,
                                   gettext("Error name "
                                           "input.\n"));
                    rv = KC_ERR_USAGE;
                } else {
                    kmf_free_dn(&respDN);
                    ocsp_set_attr++;
                }
            }
            break;
        case 'A':
            plc.VAL_OCSP_RESP_CERT_SERIAL =
                get_string(optarg_av, &rv);
            if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) {
                (void) fprintf(stderr,
                               gettext("Error serial input.\n"));
            } else {
                uchar_t *bytes = NULL;
                size_t bytelen;

                ret = kmf_hexstr_to_bytes((uchar_t *)
                                          plc.VAL_OCSP_RESP_CERT_SERIAL,
                                          &bytes, &bytelen);
                if (ret != KMF_OK || bytes == NULL) {
                    (void) fprintf(stderr,
                                   gettext("serial number "
                                           "must be specified as a "
                                           "hex number "
                                           "(ex: 0x0102030405"
                                           "ffeeddee)\n"));
                    rv = KC_ERR_USAGE;
                    break;
                }
                if (bytes != NULL)
                    free(bytes);
                ocsp_set_attr++;
            }
            break;
        case 'c':
            plc.VAL_CRL_BASEFILENAME =
                get_string(optarg_av, &rv);
            if (plc.VAL_CRL_BASEFILENAME == NULL) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
            } else {
                crl_set_attr++;
            }
            break;
        case 'I':
            plc.VAL_CRL_DIRECTORY =
                get_string(optarg_av, &rv);
            if (plc.VAL_CRL_DIRECTORY == NULL) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
            } else {
                crl_set_attr++;
            }
            break;
        case 'g':
            plc.VAL_CRL_GET_URI = get_boolean(optarg_av);
            if (plc.VAL_CRL_GET_URI == -1) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
                rv = KC_ERR_USAGE;
            } else {
                crl_set_attr++;
            }
            break;
        case 'X':
            plc.VAL_CRL_PROXY = get_string(optarg_av, &rv);
            if (plc.VAL_CRL_PROXY == NULL) {
                (void) fprintf(stderr,
                               gettext("Error proxy input.\n"));
            } else {
                crl_set_attr++;
            }
            break;
        case 'S':
            plc.VAL_CRL_IGNORE_SIGN =
                get_boolean(optarg_av);
            if (plc.VAL_CRL_IGNORE_SIGN == -1) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
                rv = KC_ERR_USAGE;
            } else {
                crl_set_attr++;
            }
            break;
        case 'D':
            plc.VAL_CRL_IGNORE_DATE =
                get_boolean(optarg_av);
            if (plc.VAL_CRL_IGNORE_DATE == -1) {
                (void) fprintf(stderr,
                               gettext("Error boolean input.\n"));
                rv = KC_ERR_USAGE;
            } else {
                crl_set_attr++;
            }
            break;
        case 'u':
            plc.ku_bits = parseKUlist(optarg_av);
            if (plc.ku_bits == 0) {
                (void) fprintf(stderr, gettext(
                                   "Error keyusage input.\n"));
                rv = KC_ERR_USAGE;
            }
            break;
        case 'E':
            if (parseEKUNames(optarg_av, &plc) != 0) {
                (void) fprintf(stderr,
                               gettext("Error EKU input.\n"));
                rv = KC_ERR_USAGE;
            }
            break;
        case 'O':
            if (parseEKUOIDs(optarg_av, &plc) != 0) {
                (void) fprintf(stderr,
                               gettext("Error EKU OID input.\n"));
                rv = KC_ERR_USAGE;
            }
            break;
        case 'm':
            plc.mapper.mapname = get_string(optarg_av, &rv);
            if (plc.mapper.mapname == NULL) {
                (void) fprintf(stderr,
                               gettext("Error mapper-name "
                                       "input.\n"));
            }
            break;
        case 'M':
            plc.mapper.dir = get_string(optarg_av, &rv);
            if (plc.mapper.dir == NULL) {
                (void) fprintf(stderr,
                               gettext("Error mapper-dir "
                                       "input.\n"));
            }
            break;
        case 'Q':
            plc.mapper.pathname = get_string(optarg_av,
                                             &rv);
            if (plc.mapper.pathname == NULL) {
                (void) fprintf(stderr,
                               gettext("Error mapper-pathname "
                                       "input.\n"));
            }
            break;
        case 'q':
            plc.mapper.options = get_string(optarg_av, &rv);
            if (plc.mapper.options == NULL) {
                (void) fprintf(stderr,
                               gettext("Error mapper-options "
                                       "input.\n"));
            }
            break;
        default:
            (void) fprintf(stderr,
                           gettext("Error input option.\n"));
            rv = KC_ERR_USAGE;
            break;
        }

        if (rv != KC_OK)
            goto out;
    }

    /* No additional args allowed. */
    argc -= optind_av;
    if (argc) {
        (void) fprintf(stderr,
                       gettext("Error input option\n"));
        rv = KC_ERR_USAGE;
        goto out;
    }

    if (filename == NULL) {
        filename = strdup(KMF_DEFAULT_POLICY_FILE);
        if (filename == NULL) {
            rv = KC_ERR_MEMORY;
            goto out;
        }
    }

    /*
     * Must have a policy name. The policy name can not be default
     * if using the default policy file.
     */
    if (plc.name == NULL) {
        (void) fprintf(stderr,
                       gettext("You must specify a policy name\n"));
        rv = KC_ERR_USAGE;
        goto out;
    } else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 &&
               strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) {
        (void) fprintf(stderr,
                       gettext("Can not create a default policy in the default "
                               "policy file\n"));
        rv = KC_ERR_USAGE;
        goto out;
    }

    /*
     * If the policy file exists and the policy is in the policy file
     * already, we will not create it again.
     */
    if (access(filename, R_OK) == 0) {
        POLICY_LIST *plclist = NULL, *pnode;
        int found = 0;

        rv = load_policies(filename, &plclist);
        if (rv != KMF_OK)
            goto out;

        pnode = plclist;
        while (pnode != NULL && !found) {
            if (strcmp(plc.name, pnode->plc.name) == 0)
                found++;
            pnode = pnode->next;
        }
        free_policy_list(plclist);

        if (found) {
            (void) fprintf(stderr,
                           gettext("Could not create policy \"%s\" - exists "
                                   "already\n"), plc.name);
            rv = KC_ERR_USAGE;
            goto out;
        }
    }

    /*
     * If any OCSP attribute is set, turn on the OCSP checking flag.
     * Also set "has_resp_cert" to be true, if the responder cert
     * is provided.
     */
    if (ocsp_set_attr > 0)
        plc.revocation |= KMF_REVOCATION_METHOD_OCSP;

    if (plc.VAL_OCSP_RESP_CERT.name != NULL &&
            plc.VAL_OCSP_RESP_CERT.serial != NULL) {
        plc.VAL_OCSP.has_resp_cert = B_TRUE;
    }

    /*
     * Setting mapper-name (with optional mapper-dir) and mapper-pathname is
     * mutually exclusive. Also, you cannot set options only, you need the
     * name or pathname, and you can set the directory only with the name,
     * not the pathname.
     */
    if ((plc.mapper.mapname != NULL && plc.mapper.pathname != NULL) ||
            (plc.mapper.dir != NULL && plc.mapper.pathname != NULL) ||
            (plc.mapper.dir != NULL && plc.mapper.mapname == NULL) ||
            (plc.mapper.options != NULL && plc.mapper.mapname == NULL &&
             plc.mapper.pathname == NULL)) {
        (void) fprintf(stderr,
                       gettext("Error in mapper input options\n"));
        rv = KC_ERR_USAGE;
        goto out;
    }

    /*
     * If any CRL attribute is set, turn on the CRL checking flag.
     */
    if (crl_set_attr > 0)
        plc.revocation |= KMF_REVOCATION_METHOD_CRL;

    /*
     * Does a sanity check on the new policy.
     */
    ret = kmf_verify_policy(&plc);
    if (ret != KMF_OK) {
        print_sanity_error(ret);
        rv = KC_ERR_ADD_POLICY;
        goto out;
    }

    /*
     * Add to the DB.
     */
    ret = kmf_add_policy_to_db(&plc, filename, B_FALSE);
    if (ret != KMF_OK) {
        (void) fprintf(stderr,
                       gettext("Error adding policy to database: 0x%04x\n"), ret);
        rv = KC_ERR_ADD_POLICY;
    }

out:
    if (filename != NULL)
        free(filename);

    kmf_free_policy_record(&plc);

    return (rv);
}
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 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 #5
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 #6
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 #7
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);
}