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); }
int kc_import(int argc, char *argv[]) { int rv = KC_OK; char *filename = NULL; char *infile = NULL; char *policyname = NULL; POLICY_LIST *plclist = NULL, *pnode; int opt, found = 0; extern int optind_av; extern char *optarg_av; while ((opt = getopt_av(argc, argv, "d:(dbfile)p:(policy)i:(infile)")) != EOF) { switch (opt) { case 'd': filename = get_string(optarg_av, &rv); if (filename == NULL) { (void) fprintf(stderr, gettext("Error dbfile input.\n")); } break; case 'p': policyname = get_string(optarg_av, &rv); if (policyname == NULL) { (void) fprintf(stderr, gettext("Error policy name.\n")); } break; case 'i': infile = get_string(optarg_av, &rv); if (infile == NULL) { (void) fprintf(stderr, gettext("Error infile 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; } } if (policyname == NULL) { (void) fprintf(stderr, gettext("You must specify a policy name\n")); rv = KC_ERR_USAGE; goto out; } if (infile == NULL) { (void) fprintf(stderr, gettext("You must specify a input DB file\n")); rv = KC_ERR_USAGE; goto out; } if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 && strcmp(policyname, KMF_DEFAULT_POLICY_NAME) == 0) { (void) fprintf(stderr, gettext("Can not import the default policy record to " "the system default policy database\n")); rv = KC_ERR_USAGE; goto out; } rv = load_policies(infile, &plclist); if (rv != KMF_OK) goto out; pnode = plclist; while (pnode != NULL && !found) { if (strcmp(policyname, pnode->plc.name) == 0) { KMF_RETURN ret; found++; ret = kmf_verify_policy(&pnode->plc); if (ret != KMF_OK) { print_sanity_error(ret); rv = KC_ERR_VERIFY_POLICY; break; } rv = kmf_add_policy_to_db(&pnode->plc, filename, B_FALSE); } pnode = pnode->next; } if (!found) { (void) fprintf(stderr, gettext("Could not find policy \"%s\" in %s\n"), policyname, infile); rv = KC_ERR_FIND_POLICY; } out: if (filename != NULL) free(filename); if (policyname != NULL) free(policyname); if (infile != NULL) free(infile); free_policy_list(plclist); return (rv); }
int kc_uninstall(int argc, char *argv[]) { int rv = KC_OK; int opt; extern int optind_av; extern char *optarg_av; char *keystore_name = NULL; conf_entry_t *entry = NULL; FILE *pfile = NULL; FILE *pfile_tmp = NULL; char tmpfile_name[MAXPATHLEN]; char buffer[MAXPATHLEN]; char buffer2[MAXPATHLEN]; boolean_t found; boolean_t in_package; while ((opt = getopt_av(argc, argv, "k:(keystore)")) != EOF) { switch (opt) { case 'k': if (keystore_name != NULL) rv = KC_ERR_USAGE; else { keystore_name = get_string(optarg_av, &rv); if (keystore_name == NULL) { (void) fprintf(stderr, gettext( "Error keystore 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 (keystore_name == NULL) { (void) fprintf(stderr, gettext("Error input option\n")); rv = KC_ERR_USAGE; goto out; } if (strcasecmp(keystore_name, "nss") == 0 || strcasecmp(keystore_name, "pkcs11") == 0 || strcasecmp(keystore_name, "file") == 0) { (void) fprintf(stderr, gettext("Can not uninstall the built-in keystore %s\n"), keystore_name); rv = KC_ERR_UNINSTALL; goto out; } entry = get_keystore_entry(keystore_name); if (entry == NULL) { (void) fprintf(stderr, gettext("%s does not exist.\n"), keystore_name); rv = KC_ERR_USAGE; goto out; } if ((pfile = fopen(_PATH_KMF_CONF, "r+")) == NULL) { err = errno; (void) fprintf(stderr, gettext("failed to update the configuration - %s\n"), strerror(err)); rv = KC_ERR_ACCESS; goto out; } if (lockf(fileno(pfile), F_TLOCK, 0) == -1) { err = errno; (void) fprintf(stderr, gettext("failed to lock the configuration - %s\n"), strerror(err)); rv = KC_ERR_UNINSTALL; goto out; } /* * Create a temporary file in the /etc/crypto directory. */ (void) strlcpy(tmpfile_name, CONF_TEMPFILE, sizeof (tmpfile_name)); if (mkstemp(tmpfile_name) == -1) { err = errno; (void) fprintf(stderr, gettext("failed to create a temporary file - %s\n"), strerror(err)); rv = KC_ERR_UNINSTALL; goto out; } if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) { err = errno; (void) fprintf(stderr, gettext("failed to open a temporary file - %s\n"), strerror(err)); rv = KC_ERR_UNINSTALL; goto out; } /* * Loop thru the config file. If the plugin to be uninstalled is in * a package, then just comment it off. */ in_package = B_FALSE; while (fgets(buffer, MAXPATHLEN, pfile) != NULL) { found = B_FALSE; if (buffer[0] != ' ' && buffer[0] != '\n' && buffer[0] != '\t') { if (strstr(buffer, " Start ") != NULL) { in_package = B_TRUE; } else if (strstr(buffer, " End ") != NULL) { in_package = B_FALSE; } else if (buffer[0] != '#') { char *name; int len; /* * make a copy of the original buffer to * buffer2. Also get rid of the trailing * '\n' from buffer2. */ (void) strlcpy(buffer2, buffer, MAXPATHLEN); /* get rid of trailing '\n' */ len = strlen(buffer2); if (buffer2[len-1] == '\n') { len--; } buffer2[len] = '\0'; if ((name = strtok(buffer2, SEP_COLON)) == NULL) { rv = KC_ERR_UNINSTALL; goto out; } if (strcmp(keystore_name, name) == 0) found = B_TRUE; } } if (found) { /* * If found and not in_package, then don't write * this line to the result file. */ if (in_package) { (void) snprintf(buffer2, sizeof (buffer2), "%s%s", "#", buffer); if (fputs(buffer2, pfile_tmp) == EOF) { rv = KC_ERR_UNINSTALL; goto out; } } } else { if (fputs(buffer, pfile_tmp) == EOF) { rv = KC_ERR_UNINSTALL; goto out; } } } out: if (pfile != NULL) (void) fclose(pfile); if (rv != KC_OK && pfile_tmp != NULL) (void) unlink(tmpfile_name); if (pfile_tmp != NULL) (void) fclose(pfile_tmp); if (rv == KC_OK) { if (rename(tmpfile_name, _PATH_KMF_CONF) == -1) { err = errno; (void) fprintf(stderr, gettext( "failed to update the configuration - %s"), strerror(err)); return (KC_ERR_UNINSTALL); } if (chmod(_PATH_KMF_CONF, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { err = errno; (void) fprintf(stderr, gettext( "failed to update the configuration - %s\n"), strerror(err)); return (KC_ERR_UNINSTALL); } } return (rv); }
int pk_inittoken(int argc, char *argv[]) /* ARGSUSED */ { int opt; int rv; extern int optind_av; extern char *optarg_av; char *newlabel = NULL; char *currlabel = NULL; CK_UTF8CHAR_PTR sopin; CK_ULONG sopinlen; KMF_HANDLE_T handle; /* Parse command line options. Do NOT i18n/l10n. */ while ((opt = getopt_av(argc, argv, "n:(newlabel)" "l:(currlabel)")) != EOF) { switch (opt) { case 'l': /* token specifier */ if (currlabel) return (PK_ERR_USAGE); currlabel = optarg_av; break; case 'n': /* token specifier */ if (newlabel) return (PK_ERR_USAGE); newlabel = optarg_av; break; default: return (PK_ERR_USAGE); break; } } /* No additional args allowed. */ argc -= optind_av; argv += optind_av; if (argc != 0) return (PK_ERR_USAGE); if ((rv = kmf_initialize(&handle, NULL, NULL)) != KMF_OK) return (rv); if ((rv = get_pin(gettext("Enter SO PIN:"), NULL, &sopin, &sopinlen)) != CKR_OK) { cryptoerror(LOG_STDERR, gettext("Unable to get SO PIN for token")); return (PK_ERR_SYSTEM); } if ((currlabel == NULL || !strlen(currlabel))) { cryptoerror(LOG_STDERR, gettext("The current token is not identified by label.")); return (PK_ERR_SYSTEM); } rv = kmf_pk11_init_token(handle, currlabel, newlabel, sopin, sopinlen); (void) kmf_finalize(handle); free(sopin); if (rv == KMF_ERR_AUTH_FAILED) { cryptoerror(LOG_STDERR, gettext("Incorrect passphrase.")); return (PK_ERR_SYSTEM); } else if (rv != CKR_OK) { cryptoerror(LOG_STDERR, gettext("Unable to initialize token.")); return (PK_ERR_SYSTEM); } else { (void) fprintf(stdout, gettext("Token %s initialized.\n"), (newlabel ? newlabel : currlabel)); } return (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); }
int pk_gencsr(int argc, char *argv[]) { KMF_RETURN rv; int opt; extern int optind_av; extern char *optarg_av; KMF_KEYSTORE_TYPE kstype = 0; char *subject = NULL; char *tokenname = NULL; char *dir = NULL; char *prefix = NULL; int keylen = PK_DEFAULT_KEYLENGTH; char *certlabel = NULL; char *outcsr = NULL; char *outkey = NULL; char *format = NULL; char *altname = NULL; char *kustr = NULL; char *ekustr = NULL; char *hashname = NULL; uint16_t kubits = 0; char *keytype = PK_DEFAULT_KEYTYPE; KMF_HANDLE_T kmfhandle = NULL; KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; KMF_KEY_ALG keyAlg = KMF_RSA; KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA; boolean_t interactive = B_FALSE; char *subname = NULL; KMF_CREDENTIAL tokencred = {NULL, 0}; KMF_GENERALNAMECHOICES alttype = 0; int altcrit = 0, kucrit = 0; EKU_LIST *ekulist = NULL; KMF_OID *curveoid = NULL; /* ECC */ KMF_OID *hashoid = NULL; int y_flag = 0; while ((opt = getopt_av(argc, argv, "ik:(keystore)s:(subject)n:(nickname)A:(altname)" "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)" "y:(keylen)l:(label)c:(outcsr)e:(eku)C:(curve)" "K:(outkey)F:(format)E(listcurves)h:(hash)")) != EOF) { switch (opt) { case 'A': altname = optarg_av; break; case 'i': if (interactive) return (PK_ERR_USAGE); else if (subject) { cryptoerror(LOG_STDERR, gettext("Interactive (-i) and " "subject options are mutually " "exclusive.\n")); return (PK_ERR_USAGE); } else interactive = B_TRUE; break; case 'k': kstype = KS2Int(optarg_av); if (kstype == 0) return (PK_ERR_USAGE); break; case 's': if (subject) return (PK_ERR_USAGE); else if (interactive) { cryptoerror(LOG_STDERR, gettext("Interactive (-i) and " "subject options are mutually " "exclusive.\n")); return (PK_ERR_USAGE); } else subject = optarg_av; break; case 'l': case 'n': if (certlabel) return (PK_ERR_USAGE); certlabel = optarg_av; break; case 'T': if (tokenname) return (PK_ERR_USAGE); tokenname = optarg_av; break; case 'd': dir = optarg_av; break; case 'p': if (prefix) return (PK_ERR_USAGE); prefix = optarg_av; break; case 't': keytype = optarg_av; break; case 'u': kustr = optarg_av; break; case 'y': if (sscanf(optarg_av, "%d", &keylen) != 1) { cryptoerror(LOG_STDERR, gettext("Unrecognized " "key length (%s)\n"), optarg_av); return (PK_ERR_USAGE); } y_flag++; break; case 'c': if (outcsr) return (PK_ERR_USAGE); outcsr = optarg_av; 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 'e': ekustr = 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': /* * This argument is only to be used * by itself, no other options should * be present. */ if (argc != 2) { cryptoerror(LOG_STDERR, gettext("listcurves has no other " "options.\n")); return (PK_ERR_USAGE); } show_ecc_curves(); return (0); case 'h': hashname = optarg_av; hashoid = ecc_name_to_oid(optarg_av); if (hashoid == NULL) { cryptoerror(LOG_STDERR, gettext("Unrecognized hash.\n")); return (PK_ERR_USAGE); } break; default: cryptoerror(LOG_STDERR, gettext( "unrecognized gencsr 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); } /* Assume keystore = PKCS#11 if not specified. */ if (kstype == 0) kstype = KMF_KEYSTORE_PK11TOKEN; DIR_OPTION_CHECK(kstype, dir); if (EMPTYSTRING(outcsr) && interactive) { (void) get_filename("CSR", &outcsr); } if (EMPTYSTRING(outcsr)) { (void) printf(gettext("A filename must be specified to hold" "the final certificate request data.\n")); return (PK_ERR_USAGE); } /* * verify that the outcsr file does not already exist * and that it can be created. */ rv = verify_file(outcsr); if (rv == KMF_ERR_OPEN_FILE) { cryptoerror(LOG_STDERR, gettext("Warning: file \"%s\" exists, " "will be overwritten."), outcsr); if (yesno(gettext("Continue with gencsr? "), gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { return (0); } else { /* remove the file */ (void) unlink(outcsr); } } else if (rv != KMF_OK) { cryptoerror(LOG_STDERR, gettext("Warning: error accessing \"%s\""), outcsr); return (rv); } if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { if (EMPTYSTRING(certlabel) && interactive) (void) get_certlabel(&certlabel); if (EMPTYSTRING(certlabel)) { cryptoerror(LOG_STDERR, gettext("A label must be " "specified to create a certificate request.\n")); return (PK_ERR_USAGE); } } else if (kstype == KMF_KEYSTORE_OPENSSL) { if (EMPTYSTRING(outkey) && interactive) (void) get_filename("private key", &outkey); if (EMPTYSTRING(outkey)) { cryptoerror(LOG_STDERR, gettext("A key filename " "must be specified to create a certificate " "request.\n")); return (PK_ERR_USAGE); } } if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { cryptoerror(LOG_STDERR, gettext("Error parsing format string (%s).\n"), format); return (PK_ERR_USAGE); } if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) { cryptoerror(LOG_STDERR, gettext("CSR must be DER or PEM format.\n")); return (PK_ERR_USAGE); } /* * Check the subject name. * If interactive is true, get it now interactively. */ if (interactive) { if (get_subname(&subname) != KMF_OK) { cryptoerror(LOG_STDERR, gettext("Failed to get the " "subject name interactively.\n")); return (PK_ERR_USAGE); } } else { if (EMPTYSTRING(subject)) { cryptoerror(LOG_STDERR, gettext("A subject name or " "-i must be specified to create a certificate " "request.\n")); return (PK_ERR_USAGE); } else { subname = strdup(subject); if (subname == NULL) { cryptoerror(LOG_STDERR, gettext("Out of memory.\n")); return (PK_ERR_SYSTEM); } } } if (altname != NULL) { rv = verify_altname(altname, &alttype, &altcrit); if (rv != KMF_OK) { cryptoerror(LOG_STDERR, gettext("Subject AltName " "must be specified as a name=value pair. " "See the man page for details.")); goto end; } else { /* advance the altname past the '=' sign */ char *p = strchr(altname, '='); if (p != NULL) altname = p + 1; } } if (kustr != NULL) { rv = verify_keyusage(kustr, &kubits, &kucrit); if (rv != KMF_OK) { cryptoerror(LOG_STDERR, gettext("KeyUsage " "must be specified as a comma-separated list. " "See the man page for details.")); goto end; } } if (ekustr != NULL) { rv = verify_ekunames(ekustr, &ekulist); if (rv != KMF_OK) { (void) fprintf(stderr, gettext("EKUs must " "be specified as a comma-separated list. " "See the man page for details.\n")); rv = PK_ERR_USAGE; goto end; } } if ((rv = Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg)) != 0) { cryptoerror(LOG_STDERR, gettext("Unsupported key/hash combination (%s/%s).\n"), keytype, (hashname ? hashname : "none")); goto end; } 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 && !y_flag && kstype == KMF_KEYSTORE_NSS) keylen = 1024; if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 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 ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); return (PK_ERR_USAGE); } if (kstype == KMF_KEYSTORE_NSS) { if (dir == NULL) dir = PK_DEFAULT_DIRECTORY; rv = gencsr_nss(kmfhandle, tokenname, subname, altname, alttype, altcrit, certlabel, dir, prefix, keyAlg, keylen, kubits, kucrit, fmt, outcsr, &tokencred, ekulist, sigAlg, curveoid); } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { rv = gencsr_pkcs11(kmfhandle, tokenname, subname, altname, alttype, altcrit, certlabel, keyAlg, keylen, kubits, kucrit, fmt, outcsr, &tokencred, ekulist, sigAlg, curveoid); } else if (kstype == KMF_KEYSTORE_OPENSSL) { rv = gencsr_file(kmfhandle, keyAlg, keylen, fmt, subname, altname, alttype, altcrit, kubits, kucrit, outcsr, outkey, ekulist, sigAlg); } end: if (rv != KMF_OK) { display_error(kmfhandle, rv, gettext("Error creating CSR or keypair")); if (rv == KMF_ERR_RDN_PARSER) { cryptoerror(LOG_STDERR, gettext("subject or " "issuer name must be in proper DN format.\n")); } } if (ekulist != NULL) free_eku_list(ekulist); if (subname) free(subname); if (tokencred.cred != NULL) free(tokencred.cred); (void) kmf_finalize(kmfhandle); if (rv != KMF_OK) return (PK_ERR_USAGE); return (0); }
int pk_gencert(int argc, char *argv[]) { int rv; int opt; extern int optind_av; extern char *optarg_av; KMF_KEYSTORE_TYPE kstype = 0; char *subject = NULL; char *tokenname = NULL; char *dir = NULL; char *prefix = NULL; char *keytype = PK_DEFAULT_KEYTYPE; int keylen = PK_DEFAULT_KEYLENGTH; char *trust = NULL; char *lifetime = NULL; char *certlabel = NULL; char *outcert = NULL; char *outkey = NULL; char *format = NULL; char *serstr = NULL; char *altname = NULL; char *keyusagestr = NULL; char *ekustr = NULL; char *hashname = NULL; KMF_GENERALNAMECHOICES alttype = 0; KMF_BIGINT serial = { NULL, 0 }; uint32_t ltime; KMF_HANDLE_T kmfhandle = NULL; KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; KMF_KEY_ALG keyAlg = KMF_RSA; KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA; boolean_t interactive = B_FALSE; char *subname = NULL; KMF_CREDENTIAL tokencred = { NULL, 0 }; uint16_t kubits = 0; int altcrit = 0, kucrit = 0; EKU_LIST *ekulist = NULL; KMF_OID *curveoid = NULL; /* ECC */ KMF_OID *hashoid = NULL; int y_flag = 0; while ((opt = getopt_av(argc, argv, "ik:(keystore)s:(subject)n:(nickname)A:(altname)" "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)" "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)" "K:(outkey)S:(serial)F:(format)u:(keyusage)C:(curve)" "E(listcurves)h:(hash)")) != EOF) { if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av)) return (PK_ERR_USAGE); switch (opt) { case 'A': altname = optarg_av; break; case 'i': if (interactive || subject) return (PK_ERR_USAGE); else interactive = B_TRUE; break; case 'k': kstype = KS2Int(optarg_av); if (kstype == 0) return (PK_ERR_USAGE); break; case 's': if (interactive || subject) return (PK_ERR_USAGE); else subject = optarg_av; break; case 'l': case 'n': if (certlabel) return (PK_ERR_USAGE); certlabel = 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 'u': keyusagestr = 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 'r': if (trust) return (PK_ERR_USAGE); trust = optarg_av; break; case 'L': if (lifetime) return (PK_ERR_USAGE); lifetime = optarg_av; break; case 'c': if (outcert) return (PK_ERR_USAGE); outcert = optarg_av; break; case 'K': if (outkey) return (PK_ERR_USAGE); outkey = optarg_av; break; case 'S': serstr = optarg_av; break; case 'F': if (format) return (PK_ERR_USAGE); format = optarg_av; break; case 'e': ekustr = 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': /* * This argument is only to be used * by itself, no other options should * be present. */ if (argc != 2) { cryptoerror(LOG_STDERR, gettext("listcurves has no other " "options.\n")); return (PK_ERR_USAGE); } show_ecc_curves(); return (0); case 'h': hashname = optarg_av; hashoid = ecc_name_to_oid(optarg_av); if (hashoid == NULL) { cryptoerror(LOG_STDERR, gettext("Unrecognized hash.\n")); return (PK_ERR_USAGE); } break; 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; if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { if (interactive && EMPTYSTRING(certlabel)) { (void) get_certlabel(&certlabel); } /* It better not be empty now */ if (EMPTYSTRING(certlabel)) { cryptoerror(LOG_STDERR, gettext("A label must be " "specified to create a self-signed certificate." "\n")); return (PK_ERR_USAGE); } } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) { cryptoerror(LOG_STDERR, gettext("A certificate filename must " "be specified to create a self-signed certificate.\n")); return (PK_ERR_USAGE); } 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 (Str2Lifetime(lifetime, <ime) != 0) { cryptoerror(LOG_STDERR, gettext("Error parsing lifetime string\n")); return (PK_ERR_USAGE); } if (Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg) != 0) { cryptoerror(LOG_STDERR, gettext("Unsupported key/hash combination (%s/%s).\n"), keytype, (hashname ? hashname : "none")); 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); } /* Adjust default keylength for NSS and DSA */ if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS) keylen = 1024; /* * Check the subject name. * If interactive is true, get it now interactively. */ if (interactive) { subname = NULL; if (get_subname(&subname) != KMF_OK || subname == NULL) { cryptoerror(LOG_STDERR, gettext("Failed to get the " "subject name interactively.\n")); return (PK_ERR_USAGE); } if (serstr == NULL) { (void) get_serial(&serstr); } } else { if (EMPTYSTRING(subject)) { cryptoerror(LOG_STDERR, gettext("A subject name or " "-i must be specified to create a self-signed " "certificate.\n")); return (PK_ERR_USAGE); } else { subname = strdup(subject); if (subname == NULL) { cryptoerror(LOG_STDERR, gettext("Out of memory.\n")); return (PK_ERR_SYSTEM); } } } if (serstr == NULL) { (void) fprintf(stderr, gettext("A serial number " "must be specified as a hex number when creating" " a self-signed certificate " "(ex: serial=0x0102030405feedface)\n")); rv = PK_ERR_USAGE; goto end; } else { uchar_t *bytes = NULL; size_t bytelen; rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); if (rv != KMF_OK || bytes == NULL) { (void) fprintf(stderr, gettext("serial number " "must be specified as a hex number " "(ex: 0x0102030405ffeeddee)\n")); rv = PK_ERR_USAGE; goto end; } serial.val = bytes; serial.len = bytelen; } if (altname != NULL) { rv = verify_altname(altname, &alttype, &altcrit); if (rv != KMF_OK) { (void) fprintf(stderr, gettext("Subject AltName " "must be specified as a name=value pair. " "See the man page for details.\n")); rv = PK_ERR_USAGE; goto end; } else { /* advance the altname past the '=' sign */ char *p = strchr(altname, '='); if (p != NULL) altname = p + 1; } } if (keyusagestr != NULL) { rv = verify_keyusage(keyusagestr, &kubits, &kucrit); if (rv != KMF_OK) { (void) fprintf(stderr, gettext("KeyUsage " "must be specified as a comma-separated list. " "See the man page for details.\n")); rv = PK_ERR_USAGE; goto end; } } if (ekustr != NULL) { rv = verify_ekunames(ekustr, &ekulist); if (rv != KMF_OK) { (void) fprintf(stderr, gettext("EKUs must " "be specified as a comma-separated list. " "See the man page for details.\n")); rv = PK_ERR_USAGE; goto end; } } 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; } if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 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 = gencert_nss(kmfhandle, tokenname, subname, altname, alttype, altcrit, certlabel, dir, prefix, keyAlg, sigAlg, keylen, trust, ltime, &serial, kubits, kucrit, &tokencred, ekulist, curveoid); } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { rv = gencert_pkcs11(kmfhandle, tokenname, subname, altname, alttype, altcrit, certlabel, keyAlg, sigAlg, keylen, ltime, &serial, kubits, kucrit, &tokencred, ekulist, curveoid); } else if (kstype == KMF_KEYSTORE_OPENSSL) { rv = gencert_file(kmfhandle, keyAlg, sigAlg, keylen, fmt, ltime, subname, altname, alttype, altcrit, &serial, kubits, kucrit, outcert, outkey, ekulist); } if (rv != KMF_OK) display_error(kmfhandle, rv, gettext("Error creating certificate and keypair")); end: if (ekulist != NULL) free_eku_list(ekulist); if (subname) free(subname); if (tokencred.cred != NULL) free(tokencred.cred); if (serial.val != NULL) free(serial.val); (void) kmf_finalize(kmfhandle); return (rv); }
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); }