Esempio n. 1
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
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, &ltime) != 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);
}
Esempio n. 8
0
int
pk_download(int argc, char *argv[])
{
	int rv;
	int opt;
	extern int	optind_av;
	extern char	*optarg_av;
	int oclass = 0;
	char *url = NULL;
	char *http_proxy = NULL;
	char *dir = NULL;
	char *outfile = NULL;
	char *proxy = NULL;
	int  proxy_port = 0;
	KMF_HANDLE_T	kmfhandle = NULL;
	KMF_ENCODE_FORMAT format;
	KMF_RETURN ch_rv = KMF_OK;
	char *fullpath = NULL;
	KMF_DATA cert = { 0, NULL };
	KMF_DATA cert_der = { 0, NULL };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	if (fullpath)
		free(fullpath);

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

	(void) kmf_finalize(kmfhandle);
	return (rv);
}