gencert.c revision 2c9a247fb01631b3eb3b85a1127e72f0b60ae108
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <libgen.h>
#include <errno.h>
#include <cryptoutil.h>
#include <security/cryptoki.h>
#include "common.h"
#include <kmfapi.h>
#define SET_VALUE(f, s) \
kmfrv = f; \
gettext("Failed to set %s: 0x%02x\n"), \
s, kmfrv); \
goto cleanup; \
}
static int
{
int numattr = 0;
/* If the subject name cannot be parsed, flag it now and exit */
gettext("Subject name cannot be parsed.\n"));
return (PK_ERR_USAGE);
}
/* For a self-signed cert, the issuser and subject are the same */
gettext("Subject name cannot be parsed.\n"));
return (PK_ERR_USAGE);
}
/* Select a PKCS11 token */
return (kmfrv);
}
/*
* Share the "genkeypair" routine for creating the keypair.
*/
return (kmfrv);
"keypair");
"serial number");
"validity time");
"signature algorithm");
"subject name");
"issuer name");
if (kubits != 0)
"KeyUsage");
int i;
"Extended Key Usage");
}
}
/*
* Construct attributes for the kmf_sign_cert operation.
*/
numattr = 0;
numattr++;
&prik, sizeof (KMF_KEY_HANDLE_ATTR));
numattr++;
/* cert data that is to be signed */
&signedCert, sizeof (KMF_X509_CERTIFICATE));
numattr++;
/* output buffer for the signed cert */
numattr++;
numattr++;
KMF_OK) {
goto cleanup;
}
/*
* Store the cert in the DB.
*/
numattr = 0;
numattr++;
numattr++;
numattr++;
}
/*
* If kmf_sign_cert or kmf_store_cert failed, then we need to clean up
* the key pair from the token.
*/
/* delete the public key */
numattr = 0;
numattr++;
numattr++;
sizeof (KMF_CREDENTIAL));
numattr++;
}
attrlist);
/* delete the private key */
numattr = 0;
numattr++;
numattr++;
sizeof (KMF_CREDENTIAL));
numattr++;
}
attrlist);
}
return (kmfrv);
}
static int
{
char *fullcertpath = NULL;
char *fullkeypath = NULL;
int numattr = 0;
gettext("No output file was specified for "
"the cert or key\n"));
return (PK_ERR_USAGE);
}
if (verify_file(fullcertpath)) {
gettext("Cannot write the indicated output "
"certificate file (%s).\n"), fullcertpath);
return (PK_ERR_USAGE);
}
/* If the subject name cannot be parsed, flag it now and exit */
return (PK_ERR_USAGE);
}
/* For a self-signed cert, the issuser and subject are the same */
return (PK_ERR_USAGE);
}
/*
* Share the "genkeypair" routine for creating the keypair.
*/
return (kmfrv);
"keypair");
"serial number");
"validity time");
"signature algorithm");
"subject name");
"issuer name");
if (kubits != 0)
"KeyUsage");
int i;
}
}
/*
* Construct attributes for the kmf_sign_cert operation.
*/
numattr = 0;
numattr++;
&prik, sizeof (KMF_KEY_HANDLE_ATTR));
numattr++;
/* cert data that is to be signed */
&signedCert, sizeof (KMF_X509_CERTIFICATE));
numattr++;
/* output buffer for the signed cert */
numattr++;
numattr++;
KMF_OK) {
goto cleanup;
}
/*
* Store the cert in the DB.
*/
numattr = 0;
numattr++;
numattr++;
numattr++;
numattr++;
if (fullkeypath != NULL)
if (fullcertpath != NULL)
return (kmfrv);
}
static KMF_RETURN
{
int numattr = 0;
return (kmfrv);
/* If the subject name cannot be parsed, flag it now and exit */
gettext("Subject name cannot be parsed.\n"));
return (PK_ERR_USAGE);
}
/* For a self-signed cert, the issuser and subject are the same */
gettext("Subject name cannot be parsed.\n"));
return (PK_ERR_USAGE);
}
return (kmfrv);
"keypair");
"serial number");
"validity time");
"signature algorithm");
"subject name");
"issuer name");
if (kubits)
"subjectAltName");
int i;
}
}
/*
* Construct attributes for the kmf_sign_cert operation.
*/
numattr = 0;
numattr++;
&prik, sizeof (KMF_KEY_HANDLE_ATTR));
numattr++;
/* cert data that is to be signed */
&signedCert, sizeof (KMF_X509_CERTIFICATE));
numattr++;
/* output buffer for the signed cert */
numattr++;
numattr++;
KMF_OK) {
goto cleanup;
}
/*
* Store the cert in the DB.
*/
numattr = 0;
numattr++;
numattr++;
numattr++;
}
numattr++;
}
numattr++;
}
return (kmfrv);
}
int
{
int rv;
int opt;
extern int optind_av;
extern char *optarg_av;
KMF_KEYSTORE_TYPE kstype = 0;
char *keytype = PK_DEFAULT_KEYTYPE;
int keylen = PK_DEFAULT_KEYLENGTH;
char *keyusagestr = NULL;
int y_flag = 0;
"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) {
return (PK_ERR_USAGE);
switch (opt) {
case 'A':
break;
case 'i':
if (interactive || subject)
return (PK_ERR_USAGE);
else
break;
case 'k':
if (kstype == 0)
return (PK_ERR_USAGE);
break;
case 's':
if (interactive || subject)
return (PK_ERR_USAGE);
else
break;
case 'l':
case 'n':
if (certlabel)
return (PK_ERR_USAGE);
break;
case 'T':
if (tokenname)
return (PK_ERR_USAGE);
break;
case 'd':
if (dir)
return (PK_ERR_USAGE);
break;
case 'p':
if (prefix)
return (PK_ERR_USAGE);
break;
case 't':
break;
case 'u':
break;
case 'y':
&keylen) != 1) {
gettext("key length must be"
"a numeric value (%s)\n"),
return (PK_ERR_USAGE);
}
y_flag++;
break;
case 'r':
if (trust)
return (PK_ERR_USAGE);
break;
case 'L':
if (lifetime)
return (PK_ERR_USAGE);
break;
case 'c':
if (outcert)
return (PK_ERR_USAGE);
break;
case 'K':
if (outkey)
return (PK_ERR_USAGE);
break;
case 'S':
break;
case 'F':
if (format)
return (PK_ERR_USAGE);
break;
case 'e':
break;
case 'C':
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) {
gettext("listcurves has no other "
"options.\n"));
return (PK_ERR_USAGE);
}
return (0);
case 'h':
gettext("Unrecognized hash.\n"));
return (PK_ERR_USAGE);
}
break;
default:
return (PK_ERR_USAGE);
}
}
/* No additional args allowed. */
if (argc) {
return (PK_ERR_USAGE);
}
return (PK_ERR_USAGE);
}
/* Assume keystore = PKCS#11 if not specified. */
if (kstype == 0)
(void) get_certlabel(&certlabel);
}
/* It better not be empty now */
if (EMPTYSTRING(certlabel)) {
"specified to create a self-signed certificate."
"\n"));
return (PK_ERR_USAGE);
}
"be specified to create a self-signed certificate.\n"));
return (PK_ERR_USAGE);
}
gettext("Error parsing format string (%s).\n"),
format);
return (PK_ERR_USAGE);
}
gettext("Error parsing lifetime string\n"));
return (PK_ERR_USAGE);
}
return (PK_ERR_USAGE);
}
"valid for EC keytypes.\n"));
return (PK_ERR_USAGE);
}
"specifed when using EC keys.\n"));
return (PK_ERR_USAGE);
}
/* Adjust default keylength for NSS and DSA */
keylen = 1024;
/*
* Check the subject name.
* If interactive is true, get it now interactively.
*/
if (interactive) {
"subject name interactively.\n"));
return (PK_ERR_USAGE);
}
(void) get_serial(&serstr);
}
} else {
if (EMPTYSTRING(subject)) {
"-i must be specified to create a self-signed "
"certificate.\n"));
return (PK_ERR_USAGE);
} else {
gettext("Out of memory.\n"));
return (PK_ERR_SYSTEM);
}
}
}
"must be specified as a hex number when creating"
" a self-signed certificate "
"(ex: serial=0x0102030405feedface)\n"));
rv = PK_ERR_USAGE;
goto end;
} else {
"must be specified as a hex number "
"(ex: 0x0102030405ffeeddee)\n"));
rv = PK_ERR_USAGE;
goto end;
}
}
"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 */
if (p != NULL)
altname = p + 1;
}
}
if (keyusagestr != NULL) {
"must be specified as a comma-separated list. "
"See the man page for details.\n"));
rv = PK_ERR_USAGE;
goto end;
}
}
"be specified as a comma-separated list. "
"See the man page for details.\n"));
rv = PK_ERR_USAGE;
goto end;
}
}
"only supported with the pkcs11 and nss keystores\n"));
rv = PK_ERR_USAGE;
goto end;
}
if (kstype == KMF_KEYSTORE_NSS) {
tokenname = "internal";
} else {
}
}
}
if (kstype == KMF_KEYSTORE_NSS) {
} else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
curveoid);
} else if (kstype == KMF_KEYSTORE_OPENSSL) {
ekulist);
}
gettext("Error creating certificate and keypair"));
end:
if (subname)
(void) kmf_finalize(kmfhandle);
return (rv);
}