Home | History | Annotate | Download | only in elfsign
      1   5194   johnz /*
      2   5194   johnz  * CDDL HEADER START
      3   5194   johnz  *
      4   5194   johnz  * The contents of this file are subject to the terms of the
      5   5194   johnz  * Common Development and Distribution License (the "License").
      6   5194   johnz  * You may not use this file except in compliance with the License.
      7   5194   johnz  *
      8   5194   johnz  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9   5194   johnz  * or http://www.opensolaris.org/os/licensing.
     10   5194   johnz  * See the License for the specific language governing permissions
     11   5194   johnz  * and limitations under the License.
     12   5194   johnz  *
     13   5194   johnz  * When distributing Covered Code, include this CDDL HEADER in each
     14   5194   johnz  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15   5194   johnz  * If applicable, add the following below this CDDL HEADER, with the
     16   5194   johnz  * fields enclosed by brackets "[]" replaced with your own identifying
     17   5194   johnz  * information: Portions Copyright [yyyy] [name of copyright owner]
     18   5194   johnz  *
     19   5194   johnz  * CDDL HEADER END
     20   5194   johnz  */
     21   5194   johnz 
     22   5194   johnz /*
     23  10671    John  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24   5194   johnz  * Use is subject to license terms.
     25   5194   johnz  */
     26   5194   johnz 
     27   5194   johnz /*
     28   5194   johnz  * Developer command for adding the signature section to an ELF object
     29   5194   johnz  * PSARC 2001/488
     30   5194   johnz  *
     31   5194   johnz  * DEBUG Information:
     32   5194   johnz  * This command uses the cryptodebug() function from libcryptoutil.
     33   5194   johnz  * Set SUNW_CRYPTO_DEBUG to stderr or syslog for all debug to go to auth.debug
     34   5194   johnz  */
     35   5194   johnz 
     36   5194   johnz #include <stdio.h>
     37   5194   johnz #include <stdlib.h>
     38   5194   johnz #include <stdarg.h>
     39   5194   johnz #include <limits.h>
     40   5194   johnz #include <time.h>
     41   5194   johnz #include <unistd.h>
     42   5194   johnz #include <sys/types.h>
     43   5194   johnz #include <sys/stat.h>
     44   5194   johnz #include <fcntl.h>
     45   5194   johnz #include <libintl.h>
     46   5194   johnz #include <locale.h>
     47   5194   johnz #include <errno.h>
     48   5194   johnz #include <strings.h>
     49   5194   johnz #include <langinfo.h>
     50   5194   johnz 
     51   5194   johnz #include <cryptoutil.h>
     52   5194   johnz #include <sys/crypto/elfsign.h>
     53   5194   johnz #include <libelfsign.h>
     54   5194   johnz 
     55   5194   johnz #include <kmfapi.h>
     56   5194   johnz 
     57   5194   johnz #define	SIGN		"sign"
     58   5194   johnz #define	SIGN_OPTS	"ac:e:F:k:P:T:v"
     59   5194   johnz #define	VERIFY		"verify"
     60   5194   johnz #define	VERIFY_OPTS	"c:e:v"
     61   5194   johnz #define	REQUEST		"request"
     62   5194   johnz #define	REQUEST_OPTS	"i:k:r:T:"
     63   5194   johnz #define	LIST		"list"
     64   5194   johnz #define	LIST_OPTS	"c:e:f:"
     65   5194   johnz 
     66   5194   johnz enum cmd_e {
     67   5194   johnz 	ES_SIGN,
     68   5194   johnz 	ES_VERIFY,
     69   5194   johnz 	ES_REQUEST,
     70   5194   johnz 	ES_LIST
     71   5194   johnz };
     72   5194   johnz 
     73   5194   johnz enum field_e {
     74   5194   johnz 	FLD_UNKNOWN,
     75   5194   johnz 	FLD_SUBJECT,
     76   5194   johnz 	FLD_ISSUER,
     77   5194   johnz 	FLD_FORMAT,
     78   5194   johnz 	FLD_SIGNER,
     79   5194   johnz 	FLD_TIME
     80   5194   johnz };
     81   5194   johnz 
     82   5194   johnz #define	MIN_ARGS	3	/* The minimum # args to do anything */
     83   5194   johnz #define	ES_DEFAULT_KEYSIZE 1024
     84   5194   johnz 
     85   5194   johnz static struct {
     86   5194   johnz 	enum cmd_e	cmd;	/* sub command: sign | verify | request */
     87   5194   johnz 	char	*cert;		/* -c <certificate_file> | */
     88   5194   johnz 				/* -r <certificate_request_file> */
     89   5194   johnz 	char	**elfobj;	/* -e <elf_object> */
     90   5194   johnz 	int	elfcnt;
     91   5194   johnz 	enum ES_ACTION	es_action;
     92   5194   johnz 	ELFsign_t	ess;	/* libelfsign opaque "state" */
     93   5194   johnz 	int	extracnt;
     94   5194   johnz 	enum field_e	field;	/* -f <field> */
     95   5194   johnz 	char internal_req;	/* Sun internal certificate request */
     96   5194   johnz 	char	*pinpath;	/* -P <pin> */
     97   5194   johnz 	char	*privpath;	/* -k <private_key> */
     98   5194   johnz 	char	*token_label;	/* -T <token_label> */
     99   5194   johnz 	boolean_t verbose;	/* chatty output */
    100   5194   johnz } cmd_info;
    101   5194   johnz 
    102   5194   johnz enum ret_e {
    103   5194   johnz 	EXIT_OKAY,
    104   5194   johnz 	EXIT_INVALID_ARG,
    105   5194   johnz 	EXIT_VERIFY_FAILED,
    106   5194   johnz 	EXIT_CANT_OPEN_ELF_OBJECT,
    107   5194   johnz 	EXIT_BAD_CERT,
    108   5194   johnz 	EXIT_BAD_PRIVATEKEY,
    109   5194   johnz 	EXIT_SIGN_FAILED,
    110   5194   johnz 	EXIT_VERIFY_FAILED_UNSIGNED,
    111   5194   johnz 	EXIT_CSR_FAILED,
    112   5194   johnz 	EXIT_MEMORY_ERROR
    113   5194   johnz };
    114   5194   johnz 
    115   5194   johnz struct field_s {
    116   5194   johnz 	char	*name;
    117   5194   johnz 	enum field_e	field;
    118   5194   johnz } fields[] = {
    119   5194   johnz 	{ "subject", FLD_SUBJECT },
    120   5194   johnz 	{ "issuer", FLD_ISSUER },
    121   5194   johnz 	{ "format", FLD_FORMAT },
    122   5194   johnz 	{ "signer", FLD_SIGNER },
    123   5194   johnz 	{ "time", FLD_TIME },
    124   5194   johnz 	NULL, 0
    125   5194   johnz };
    126   5194   johnz 
    127   5194   johnz typedef enum ret_e ret_t;
    128   5194   johnz 
    129   5194   johnz static void usage(void);
    130   5194   johnz static ret_t getelfobj(char *);
    131   5194   johnz static char *getpin(void);
    132   5194   johnz static ret_t do_sign(char *);
    133   5194   johnz static ret_t do_verify(char *);
    134   5194   johnz static ret_t do_cert_request(char *);
    135   5194   johnz static ret_t do_gen_esa(char *);
    136   5194   johnz static ret_t do_list(char *);
    137   5194   johnz static void es_error(const char *fmt, ...);
    138   5194   johnz static char *time_str(time_t t);
    139   5194   johnz static void sig_info_print(struct ELFsign_sig_info *esip);
    140   5194   johnz 
    141   5194   johnz int
    142   5194   johnz main(int argc, char **argv)
    143   5194   johnz {
    144   5194   johnz 	extern char *optarg;
    145   5194   johnz 	char *scmd = NULL;
    146   5194   johnz 	char *opts;		/* The set of flags for cmd */
    147   5194   johnz 	int errflag = 0;	/* We had an options parse error */
    148   5194   johnz 	char c;			/* current getopts flag */
    149   5194   johnz 	ret_t (*action)(char *);	/* Function pointer for the action */
    150   5194   johnz 	ret_t ret;
    151   5194   johnz 
    152   5194   johnz 	(void) setlocale(LC_ALL, "");
    153   5194   johnz #if !defined(TEXT_DOMAIN)	/* Should be defiend by cc -D */
    154   5194   johnz #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
    155   5194   johnz #endif
    156   5194   johnz 	(void) textdomain(TEXT_DOMAIN);
    157   5194   johnz 
    158   5194   johnz 	cryptodebug_init("elfsign");
    159   5194   johnz 
    160   5194   johnz 	if (argc < MIN_ARGS) {
    161   5194   johnz 		es_error(gettext("invalid number of arguments"));
    162   5194   johnz 		usage();
    163   5194   johnz 		return (EXIT_INVALID_ARG);
    164   5194   johnz 	}
    165   5194   johnz 
    166   5194   johnz 	scmd = argv[1];
    167   5194   johnz 	cmd_info.cert = NULL;
    168   5194   johnz 	cmd_info.elfobj = NULL;
    169   5194   johnz 	cmd_info.elfcnt = 0;
    170   5194   johnz 	cmd_info.es_action = ES_GET;
    171   5194   johnz 	cmd_info.ess = NULL;
    172   5194   johnz 	cmd_info.extracnt = 0;
    173   5194   johnz 	cmd_info.field = FLD_UNKNOWN;
    174   5194   johnz 	cmd_info.internal_req = '\0';
    175   5194   johnz 	cmd_info.pinpath = NULL;
    176   5194   johnz 	cmd_info.privpath = NULL;
    177   5194   johnz 	cmd_info.token_label = NULL;
    178   5194   johnz 	cmd_info.verbose = B_FALSE;
    179   5194   johnz 
    180   5194   johnz 	if (strcmp(scmd, SIGN) == 0) {
    181   5194   johnz 		cmd_info.cmd = ES_SIGN;
    182   5194   johnz 		opts = SIGN_OPTS;
    183   5194   johnz 		cryptodebug("cmd=sign opts=%s", opts);
    184   5194   johnz 		action = do_sign;
    185   5194   johnz 		cmd_info.es_action = ES_UPDATE_RSA_SHA1;
    186   5194   johnz 	} else if (strcmp(scmd, VERIFY) == 0) {
    187   5194   johnz 		cmd_info.cmd = ES_VERIFY;
    188   5194   johnz 		opts = VERIFY_OPTS;
    189   5194   johnz 		cryptodebug("cmd=verify opts=%s", opts);
    190   5194   johnz 		action = do_verify;
    191   5194   johnz 	} else if (strcmp(scmd, REQUEST) == 0) {
    192   5194   johnz 		cmd_info.cmd = ES_REQUEST;
    193   5194   johnz 		opts = REQUEST_OPTS;
    194   5194   johnz 		cryptodebug("cmd=request opts=%s", opts);
    195   5194   johnz 		action = do_cert_request;
    196   5194   johnz 	} else if (strcmp(scmd, LIST) == 0) {
    197   5194   johnz 		cmd_info.cmd = ES_LIST;
    198   5194   johnz 		opts = LIST_OPTS;
    199   5194   johnz 		cryptodebug("cmd=list opts=%s", opts);
    200   5194   johnz 		action = do_list;
    201   5194   johnz 	} else {
    202   5194   johnz 		es_error(gettext("Unknown sub-command: %s"),
    203   5194   johnz 		    scmd);
    204   5194   johnz 		usage();
    205   5194   johnz 		return (EXIT_INVALID_ARG);
    206   5194   johnz 	}
    207   5194   johnz 
    208   5194   johnz 	/*
    209   5194   johnz 	 * Note:  There is no need to check that optarg isn't NULL
    210   5194   johnz 	 *	  because getopt does that for us.
    211   5194   johnz 	 */
    212   5194   johnz 	while (!errflag && (c = getopt(argc - 1, argv + 1, opts)) != EOF) {
    213  10671    John 		if (strchr("ceFihkPTr", c) != NULL)
    214   5194   johnz 			cryptodebug("c=%c, '%s'", c, optarg);
    215   5194   johnz 		else
    216   5194   johnz 			cryptodebug("c=%c", c);
    217   5194   johnz 
    218   5194   johnz 		switch (c) {
    219   5194   johnz 		case 'a':
    220   5194   johnz 			/* not a normal sign operation, change the action */
    221   5194   johnz 			cmd_info.es_action = ES_GET;
    222   5194   johnz 			action = do_gen_esa;
    223   5194   johnz 			break;
    224   5194   johnz 		case 'c':
    225   5194   johnz 			cmd_info.cert = optarg;
    226   5194   johnz 			break;
    227   5194   johnz 		case 'e':
    228   5194   johnz 			cmd_info.elfcnt++;
    229   5194   johnz 			cmd_info.elfobj = (char **)realloc(cmd_info.elfobj,
    230   5194   johnz 			    sizeof (char *) * cmd_info.elfcnt);
    231   5194   johnz 			if (cmd_info.elfobj == NULL) {
    232   5194   johnz 				es_error(gettext(
    233   5194   johnz 				    "Too many elf objects specified."));
    234   5194   johnz 				return (EXIT_INVALID_ARG);
    235   5194   johnz 			}
    236   5194   johnz 			cmd_info.elfobj[cmd_info.elfcnt - 1] = optarg;
    237   5194   johnz 			break;
    238   5194   johnz 		case 'f':
    239   5194   johnz 			{
    240   5194   johnz 				struct field_s	*fp;
    241   5194   johnz 				cmd_info.field = FLD_UNKNOWN;
    242   5194   johnz 				for (fp = fields; fp->name != NULL; fp++) {
    243   5194   johnz 					if (strcasecmp(optarg, fp->name) == 0) {
    244   5194   johnz 						cmd_info.field = fp->field;
    245   5194   johnz 						break;
    246   5194   johnz 					}
    247   5194   johnz 				}
    248   5194   johnz 				if (cmd_info.field == FLD_UNKNOWN) {
    249   5194   johnz 					cryptodebug("Invalid field option");
    250   5194   johnz 					errflag++;
    251   5194   johnz 				}
    252   5194   johnz 			}
    253   5194   johnz 			break;
    254   5194   johnz 		case 'F':
    255   5194   johnz 			if (strcasecmp(optarg, ES_FMT_RSA_MD5_SHA1) == 0)
    256   5194   johnz 				cmd_info.es_action = ES_UPDATE_RSA_MD5_SHA1;
    257   5194   johnz 			else if (strcasecmp(optarg, ES_FMT_RSA_SHA1) == 0)
    258   5194   johnz 				cmd_info.es_action = ES_UPDATE_RSA_SHA1;
    259   5194   johnz 			else {
    260   5194   johnz 				cryptodebug("Invalid format option");
    261   5194   johnz 				errflag++;
    262   5194   johnz 			}
    263   5194   johnz 			break;
    264   5194   johnz 		case 'i':	 /* Undocumented internal Sun use only */
    265   5194   johnz 			cmd_info.internal_req = *optarg;
    266   5194   johnz 			break;
    267   5194   johnz 		case 'k':
    268   5194   johnz 			cmd_info.privpath = optarg;
    269   5194   johnz 			if (cmd_info.token_label != NULL ||
    270   5194   johnz 			    cmd_info.pinpath != NULL)
    271   5194   johnz 				errflag++;
    272   5194   johnz 			break;
    273   5194   johnz 		case 'P':
    274   5194   johnz 			cmd_info.pinpath = optarg;
    275   5194   johnz 			if (cmd_info.privpath != NULL)
    276   5194   johnz 				errflag++;
    277   5194   johnz 			break;
    278   5194   johnz 		case 'r':
    279   5194   johnz 			cmd_info.cert = optarg;
    280   5194   johnz 			break;
    281   5194   johnz 		case 'T':
    282   5194   johnz 			cmd_info.token_label = optarg;
    283   5194   johnz 			if (cmd_info.privpath != NULL)
    284   5194   johnz 				errflag++;
    285   5194   johnz 			break;
    286   5194   johnz 		case 'v':
    287   5194   johnz 			cmd_info.verbose = B_TRUE;
    288   5194   johnz 			break;
    289   5194   johnz 		default:
    290   5194   johnz 			errflag++;
    291   5194   johnz 		}
    292   5194   johnz 	}
    293   5194   johnz 
    294   5194   johnz 	optind++;	/* we skipped over subcommand */
    295   5194   johnz 	cmd_info.extracnt = argc - optind;
    296   5194   johnz 
    297   5194   johnz 	if (cmd_info.extracnt != 0 &&
    298   5194   johnz 	    cmd_info.cmd != ES_SIGN && cmd_info.cmd != ES_VERIFY) {
    299   5194   johnz 		cryptodebug("Extra arguments, optind=%d, argc=%d",
    300   5194   johnz 		    optind, argc);
    301   5194   johnz 		errflag++;
    302   5194   johnz 	}
    303   5194   johnz 
    304   5194   johnz 	switch (cmd_info.cmd) {
    305   5194   johnz 	case ES_VERIFY:
    306   5194   johnz 		if (cmd_info.elfcnt + argc - optind == 0) {
    307   5194   johnz 			cryptodebug("Missing elfobj");
    308   5194   johnz 			errflag++;
    309   5194   johnz 		}
    310   5194   johnz 		break;
    311   5194   johnz 
    312   5194   johnz 	case ES_SIGN:
    313   5194   johnz 		if (((cmd_info.privpath == NULL) &&
    314   5194   johnz 		    (cmd_info.token_label == NULL)) ||
    315   5194   johnz 		    (cmd_info.cert == NULL) ||
    316   5194   johnz 		    (cmd_info.elfcnt + argc - optind == 0)) {
    317   5194   johnz 			cryptodebug("Missing privpath|token_label/cert/elfobj");
    318   5194   johnz 			errflag++;
    319   5194   johnz 		}
    320   5194   johnz 		break;
    321   5194   johnz 
    322   5194   johnz 	case ES_REQUEST:
    323   5194   johnz 		if (((cmd_info.privpath == NULL) &&
    324   5194   johnz 		    (cmd_info.token_label == NULL)) ||
    325   5194   johnz 		    (cmd_info.cert == NULL)) {
    326   5194   johnz 			cryptodebug("Missing privpath|token_label/certreq");
    327   5194   johnz 			errflag++;
    328   5194   johnz 		}
    329   5194   johnz 		break;
    330   5194   johnz 	case ES_LIST:
    331   5194   johnz 		if ((cmd_info.cert != NULL) == (cmd_info.elfcnt > 0)) {
    332   5194   johnz 			cryptodebug("Neither or both of cert/elfobj");
    333   5194   johnz 			errflag++;
    334   5194   johnz 		}
    335   5194   johnz 		break;
    336   5194   johnz 	}
    337   5194   johnz 
    338   5194   johnz 	if (errflag) {
    339   5194   johnz 		usage();
    340   5194   johnz 		return (EXIT_INVALID_ARG);
    341   5194   johnz 	}
    342   5194   johnz 
    343   5194   johnz 	switch (cmd_info.cmd) {
    344   5194   johnz 	case ES_REQUEST:
    345   5194   johnz 	case ES_LIST:
    346   5194   johnz 		ret = action(NULL);
    347   5194   johnz 		break;
    348   5194   johnz 	default:
    349   5194   johnz 		{
    350   5194   johnz 		int i;
    351   5194   johnz 		ret_t	iret;
    352   5194   johnz 
    353   5194   johnz 		ret = EXIT_OKAY;
    354   5194   johnz 		iret = EXIT_OKAY;
    355   5194   johnz 		for (i = 0; i < cmd_info.elfcnt &&
    356   5194   johnz 		    (ret == EXIT_OKAY || cmd_info.cmd != ES_SIGN); i++) {
    357   5194   johnz 			iret = action(cmd_info.elfobj[i]);
    358   5194   johnz 			if (iret > ret)
    359   5194   johnz 				ret = iret;
    360   5194   johnz 		}
    361   5194   johnz 		for (i = optind; i < argc &&
    362   5194   johnz 		    (ret == EXIT_OKAY || cmd_info.cmd != ES_SIGN); i++) {
    363   5194   johnz 			iret = action(argv[i]);
    364   5194   johnz 			if (iret > ret)
    365   5194   johnz 				ret = iret;
    366   5194   johnz 		}
    367   5194   johnz 		break;
    368   5194   johnz 		}
    369   5194   johnz 	}
    370   5194   johnz 
    371   5194   johnz 	if (cmd_info.elfobj != NULL)
    372   5194   johnz 		free(cmd_info.elfobj);
    373   5194   johnz 
    374   5194   johnz 	return (ret);
    375   5194   johnz }
    376   5194   johnz 
    377   5194   johnz 
    378   5194   johnz static void
    379   5194   johnz usage(void)
    380   5194   johnz {
    381   5194   johnz /* BEGIN CSTYLED */
    382   5194   johnz 	(void) fprintf(stderr, gettext(
    383   5194   johnz  "usage:\n"
    384   5194   johnz  "\telfsign sign [-a] [-v] [-e <elf_object>] -c <certificate_file>\n"
    385   5194   johnz  "\t\t[-F <format>] -k <private_key_file> [elf_object]..."
    386   5194   johnz  "\n"
    387   5194   johnz  "\telfsign sign [-a] [-v] [-e <elf_object>] -c <certificate_file>\n"
    388   5194   johnz  "\t\t[-F <format>] -T <token_label> [-P <pin_file>] [elf_object]..."
    389   5194   johnz  "\n\n"
    390   5194   johnz  "\telfsign verify [-v] [-c <certificate_file>] [-e <elf_object>]\n"
    391   5194   johnz  "\t\t[elf_object]..."
    392   5194   johnz  "\n\n"
    393   5194   johnz  "\telfsign request -r <certificate_request_file> -k <private_key_file>"
    394   5194   johnz  "\n"
    395   5194   johnz  "\telfsign request -r <certificate_request_file> -T <token_label>"
    396   5194   johnz  "\n\n"
    397   5194   johnz  "\telfsign list -f field -c <certificate_file>"
    398   5194   johnz  "\n"
    399   5194   johnz  "\telfsign list -f field -e <elf_object>"
    400   5194   johnz  "\n"));
    401   5194   johnz /* END CSTYLED */
    402   5194   johnz }
    403   5194   johnz 
    404   5194   johnz static ret_t
    405   5194   johnz getelfobj(char *elfpath)
    406   5194   johnz {
    407   5194   johnz 	ELFsign_status_t estatus;
    408   5980   johnz 	ret_t	ret = EXIT_SIGN_FAILED;
    409   5194   johnz 
    410   5194   johnz 	estatus = elfsign_begin(elfpath, cmd_info.es_action, &(cmd_info.ess));
    411   5194   johnz 	switch (estatus) {
    412   5194   johnz 	case ELFSIGN_SUCCESS:
    413   5194   johnz 	case ELFSIGN_RESTRICTED:
    414   5194   johnz 		ret = EXIT_OKAY;
    415   5194   johnz 		break;
    416   5194   johnz 	case ELFSIGN_INVALID_ELFOBJ:
    417   5194   johnz 		es_error(gettext(
    418   5194   johnz 		    "Unable to open %s as an ELF object."),
    419   5194   johnz 		    elfpath);
    420   5194   johnz 		ret = EXIT_CANT_OPEN_ELF_OBJECT;
    421   5194   johnz 		break;
    422   5194   johnz 	default:
    423   5194   johnz 		es_error(gettext("unexpected failure: %d"), estatus);
    424   5194   johnz 		if (cmd_info.cmd == ES_SIGN) {
    425   5194   johnz 			ret = EXIT_SIGN_FAILED;
    426   5194   johnz 		} else if (cmd_info.cmd == ES_VERIFY) {
    427   5194   johnz 			ret = EXIT_VERIFY_FAILED;
    428   5194   johnz 		}
    429   5194   johnz 	}
    430   5194   johnz 
    431   5194   johnz 	return (ret);
    432   5194   johnz }
    433   5194   johnz 
    434   5194   johnz static ret_t
    435   5194   johnz setcertpath(void)
    436   5194   johnz {
    437   5194   johnz 	ELFsign_status_t estatus;
    438   5980   johnz 	ret_t	ret = EXIT_SIGN_FAILED;
    439   5194   johnz 
    440   5194   johnz 	if (cmd_info.cert == NULL)
    441   5194   johnz 		return (EXIT_OKAY);
    442   5194   johnz 	estatus = elfsign_setcertpath(cmd_info.ess, cmd_info.cert);
    443   5194   johnz 	switch (estatus) {
    444   5194   johnz 	case ELFSIGN_SUCCESS:
    445   5194   johnz 		ret = EXIT_OKAY;
    446   5194   johnz 		break;
    447   5194   johnz 	case ELFSIGN_INVALID_CERTPATH:
    448   5194   johnz 		if (cmd_info.cert != NULL) {
    449   5194   johnz 			es_error(gettext("Unable to open %s as a certificate."),
    450   5194   johnz 			    cmd_info.cert);
    451   5194   johnz 		}
    452   5194   johnz 		ret = EXIT_BAD_CERT;
    453   5194   johnz 		break;
    454   5194   johnz 	default:
    455   6960  bubbva 		es_error(gettext("unusable certificate: %s"), cmd_info.cert);
    456   5194   johnz 		if (cmd_info.cmd == ES_SIGN) {
    457   5194   johnz 			ret = EXIT_SIGN_FAILED;
    458   5194   johnz 		} else if (cmd_info.cmd == ES_VERIFY) {
    459   5194   johnz 			ret = EXIT_VERIFY_FAILED;
    460   5194   johnz 		}
    461   5194   johnz 	}
    462   5194   johnz 
    463   5194   johnz 	return (ret);
    464   5194   johnz }
    465   5194   johnz 
    466   5194   johnz /*
    467   5194   johnz  * getpin - return pointer to token PIN in static storage
    468   5194   johnz  */
    469   5194   johnz static char *
    470   5194   johnz getpin(void)
    471   5194   johnz {
    472   5194   johnz 	static char	pinbuf[PASS_MAX + 1];
    473   5194   johnz 	char	*pp;
    474   5194   johnz 	FILE	*pinfile;
    475   5194   johnz 
    476   5194   johnz 	if (cmd_info.pinpath == NULL)
    477   5194   johnz 		return (getpassphrase(
    478   5194   johnz 		    gettext("Enter PIN for PKCS#11 token: ")));
    479   5194   johnz 	if ((pinfile = fopen(cmd_info.pinpath, "r")) == NULL) {
    480   5194   johnz 		es_error(gettext("failed to open %s."),
    481   5194   johnz 		    cmd_info.pinpath);
    482   5194   johnz 		return (NULL);
    483   5194   johnz 	}
    484   5194   johnz 
    485   5194   johnz 	pp = fgets(pinbuf, sizeof (pinbuf), pinfile);
    486   5194   johnz 	(void) fclose(pinfile);
    487   5194   johnz 	if (pp == NULL) {
    488   5194   johnz 		es_error(gettext("failed to read PIN from %s."),
    489   5194   johnz 		    cmd_info.pinpath);
    490   5194   johnz 		return (NULL);
    491   5194   johnz 	}
    492   5194   johnz 	pp = &pinbuf[strlen(pinbuf) - 1];
    493   5194   johnz 	if (*pp == '\n')
    494   5194   johnz 		*pp = '\0';
    495   5194   johnz 	return (pinbuf);
    496   5194   johnz }
    497   5194   johnz 
    498   5194   johnz /*
    499   5194   johnz  * Add the .SUNW_signature sections for the ELF signature
    500   5194   johnz  */
    501   5194   johnz static ret_t
    502   5194   johnz do_sign(char *object)
    503   5194   johnz {
    504   5194   johnz 	ret_t 	ret;
    505   5194   johnz 	ELFsign_status_t	elfstat;
    506   5194   johnz 	struct filesignatures	*fssp = NULL;
    507   5194   johnz 	size_t fs_len;
    508   5194   johnz 	uchar_t sig[SIG_MAX_LENGTH];
    509   5194   johnz 	size_t	sig_len = SIG_MAX_LENGTH;
    510   5194   johnz 	uchar_t	hash[SIG_MAX_LENGTH];
    511   5194   johnz 	size_t	hash_len = SIG_MAX_LENGTH;
    512   5194   johnz 	ELFCert_t	cert = NULL;
    513   5194   johnz 	char	*dn;
    514   5194   johnz 	size_t	dn_len;
    515   5194   johnz 
    516   5194   johnz 	cryptodebug("do_sign");
    517   5194   johnz 	if ((ret = getelfobj(object)) != EXIT_OKAY)
    518   5194   johnz 		return (ret);
    519   5194   johnz 
    520   5194   johnz 	if (cmd_info.token_label &&
    521   5194   johnz 	    !elfcertlib_settoken(cmd_info.ess, cmd_info.token_label)) {
    522   5194   johnz 		es_error(gettext("Unable to access token: %s"),
    523   5194   johnz 		    cmd_info.token_label);
    524   5194   johnz 		ret = EXIT_SIGN_FAILED;
    525   5194   johnz 		goto cleanup;
    526   5194   johnz 	}
    527   5194   johnz 
    528   5194   johnz 	if ((ret = setcertpath()) != EXIT_OKAY)
    529   5194   johnz 		goto cleanup;
    530   5194   johnz 
    531   5194   johnz 	if (!elfcertlib_getcert(cmd_info.ess, cmd_info.cert, NULL, &cert,
    532   5194   johnz 	    cmd_info.es_action)) {
    533   5194   johnz 		es_error(gettext("Unable to load certificate: %s"),
    534   5194   johnz 		    cmd_info.cert);
    535   5194   johnz 		ret = EXIT_BAD_CERT;
    536   5194   johnz 		goto cleanup;
    537   5194   johnz 	}
    538   5194   johnz 
    539   5194   johnz 	if (cmd_info.privpath != NULL) {
    540   5194   johnz 		if (!elfcertlib_loadprivatekey(cmd_info.ess, cert,
    541   5194   johnz 		    cmd_info.privpath)) {
    542   5194   johnz 			es_error(gettext("Unable to load private key: %s"),
    543   5194   johnz 			    cmd_info.privpath);
    544   5194   johnz 			ret = EXIT_BAD_PRIVATEKEY;
    545   5194   johnz 			goto cleanup;
    546   5194   johnz 		}
    547   5194   johnz 	} else {
    548   5194   johnz 		char *pin = getpin();
    549   5194   johnz 		if (pin == NULL) {
    550   5194   johnz 			es_error(gettext("Unable to get PIN"));
    551   5194   johnz 			ret = EXIT_BAD_PRIVATEKEY;
    552   5194   johnz 			goto cleanup;
    553   5194   johnz 		}
    554   5194   johnz 		if (!elfcertlib_loadtokenkey(cmd_info.ess, cert,
    555   5194   johnz 		    cmd_info.token_label, pin)) {
    556   5194   johnz 			es_error(gettext("Unable to access private key "
    557   5194   johnz 			    "in token %s"), cmd_info.token_label);
    558   5194   johnz 			ret = EXIT_BAD_PRIVATEKEY;
    559   5194   johnz 			goto cleanup;
    560   5194   johnz 		}
    561   5194   johnz 	}
    562   5194   johnz 
    563   5194   johnz 	/*
    564   5194   johnz 	 * Get the DN from the certificate.
    565   5194   johnz 	 */
    566   5194   johnz 	if ((dn = elfcertlib_getdn(cert)) == NULL) {
    567   5194   johnz 		es_error(gettext("Unable to find DN in certificate %s"),
    568   5194   johnz 		    cmd_info.cert);
    569   5194   johnz 		ret = EXIT_SIGN_FAILED;
    570   5194   johnz 		goto cleanup;
    571   5194   johnz 	}
    572   5194   johnz 	dn_len = strlen(dn);
    573   5194   johnz 	cryptodebug("DN = %s", dn);
    574   5194   johnz 
    575   5194   johnz 	elfstat = elfsign_signatures(cmd_info.ess, &fssp, &fs_len, ES_GET);
    576   5194   johnz 	if (elfstat != ELFSIGN_SUCCESS) {
    577   5194   johnz 		if (elfstat != ELFSIGN_NOTSIGNED) {
    578   5194   johnz 			es_error(gettext("Unable to retrieve existing "
    579   5194   johnz 			    "signature block in %s"), object);
    580   5194   johnz 			ret = EXIT_SIGN_FAILED;
    581   5194   johnz 			goto cleanup;
    582   5194   johnz 		}
    583   5194   johnz 		fssp = NULL;
    584   5194   johnz 		/*
    585   5194   johnz 		 * force creation and naming of signature section
    586   5194   johnz 		 * so the hash doesn't change
    587   5194   johnz 		 */
    588   5194   johnz 		if (elfsign_signatures(cmd_info.ess, &fssp, &fs_len,
    589   5194   johnz 		    cmd_info.es_action) != ELFSIGN_SUCCESS) {
    590   5194   johnz 			es_error(gettext("Unable to insert "
    591   5194   johnz 			    "signature block into %s"), object);
    592   5194   johnz 			ret = EXIT_SIGN_FAILED;
    593   5194   johnz 			goto cleanup;
    594   5194   johnz 		}
    595   5194   johnz 	}
    596   5194   johnz 
    597   5194   johnz 	bzero(hash, sizeof (hash));
    598   5194   johnz 	if (elfsign_hash(cmd_info.ess, hash, &hash_len) != ELFSIGN_SUCCESS) {
    599   5194   johnz 		es_error(gettext("Unable to calculate hash of ELF object %s"),
    600   5194   johnz 		    object);
    601   5194   johnz 		ret = EXIT_SIGN_FAILED;
    602   5194   johnz 		goto cleanup;
    603   5194   johnz 	}
    604   5194   johnz 
    605   5194   johnz 	bzero(sig, sizeof (sig));
    606   5194   johnz 	if (!elfcertlib_sign(cmd_info.ess, cert,
    607   5194   johnz 	    hash, hash_len, sig, &sig_len)) {
    608   5194   johnz 		es_error(gettext("Unable to sign %s using key from %s"),
    609   5194   johnz 		    object, cmd_info.privpath ?
    610   5194   johnz 		    cmd_info.privpath : cmd_info.token_label);
    611   5194   johnz 		ret = EXIT_SIGN_FAILED;
    612   5194   johnz 		goto cleanup;
    613   5194   johnz 	}
    614   5194   johnz 
    615   5194   johnz 	{ /* DEBUG START */
    616   5194   johnz 		const int sigstr_len = sizeof (char) * sig_len * 2 + 1;
    617   5194   johnz 		char *sigstr = malloc(sigstr_len);
    618   5194   johnz 
    619   5194   johnz 		tohexstr(sig, sig_len, sigstr, sigstr_len);
    620   5194   johnz 		cryptodebug("sig value is: %s", sigstr);
    621   5194   johnz 		free(sigstr);
    622   5194   johnz 	} /* DEBUG END */
    623   5194   johnz 
    624   5194   johnz 	fssp = elfsign_insert_dso(cmd_info.ess, fssp,
    625   5194   johnz 	    dn, dn_len, sig, sig_len, NULL, 0);
    626   5194   johnz 	if (fssp == NULL) {
    627   5194   johnz 		es_error(gettext("Unable to prepare signature for %s"),
    628   5194   johnz 		    object);
    629   5194   johnz 		ret = EXIT_SIGN_FAILED;
    630   5194   johnz 		goto cleanup;
    631   5194   johnz 	}
    632   5194   johnz 	if (elfsign_signatures(cmd_info.ess, &fssp, &fs_len,
    633   5194   johnz 	    cmd_info.es_action) != ELFSIGN_SUCCESS) {
    634   5194   johnz 		es_error(gettext("Unable to update %s: with signature"),
    635   5194   johnz 		    object);
    636   5194   johnz 		ret = EXIT_SIGN_FAILED;
    637   5194   johnz 		goto cleanup;
    638   5194   johnz 	}
    639   5194   johnz 	if (cmd_info.verbose || (cmd_info.elfcnt + cmd_info.extracnt) > 1) {
    640   5194   johnz 		(void) fprintf(stdout,
    641   5194   johnz 		    gettext("elfsign: %s signed successfully.\n"),
    642   5194   johnz 		    object);
    643   5194   johnz 	}
    644   5194   johnz 	if (cmd_info.verbose) {
    645   5194   johnz 		struct ELFsign_sig_info *esip;
    646   5194   johnz 
    647   5194   johnz 		if (elfsign_sig_info(fssp, &esip)) {
    648   5194   johnz 			sig_info_print(esip);
    649   5194   johnz 			elfsign_sig_info_free(esip);
    650   5194   johnz 		}
    651   5194   johnz 	}
    652   5194   johnz 
    653   5194   johnz 	ret = EXIT_OKAY;
    654   5194   johnz 
    655   5194   johnz cleanup:
    656   5194   johnz 	free(fssp);
    657   5194   johnz 	bzero(sig, sig_len);
    658   5194   johnz 	bzero(hash, hash_len);
    659   5194   johnz 
    660   5194   johnz 	if (cert != NULL)
    661   5194   johnz 		elfcertlib_releasecert(cmd_info.ess, cert);
    662   5194   johnz 	if (cmd_info.ess != NULL)
    663   5194   johnz 		elfsign_end(cmd_info.ess);
    664   5194   johnz 
    665   5194   johnz 	return (ret);
    666   5194   johnz }
    667   5194   johnz 
    668   5194   johnz #define	ESA_ERROR(str, esa_file) {	\
    669   5194   johnz 	int realerrno = errno;		\
    670   5194   johnz 	es_error(gettext(str), esa_file, strerror(realerrno)); \
    671   5194   johnz 	goto clean_esa;			\
    672   5194   johnz }
    673   5194   johnz 
    674   5194   johnz /*
    675   5194   johnz  * Generate the elfsign activation file (.esa) for this request.
    676   5194   johnz  * The .esa file should contain the signature of main binary
    677   5194   johnz  * signed with an unlimited certificate, the DN and its own signature.
    678   5194   johnz  *
    679   5194   johnz  * The format is as follows:
    680   5194   johnz  *   -----------------------------
    681   5194   johnz  * A | main signature length     |
    682   5194   johnz  *   -----------------------------
    683   5194   johnz  * B | main signature (copy of   |
    684   5194   johnz  *   |   signature from original |
    685   5194   johnz  *   |   limited-use binary      |
    686   5194   johnz  *   -----------------------------
    687   5194   johnz  * C | signing DN length         |
    688   5194   johnz  *   -----------------------------
    689   5194   johnz  * D | signing DN                |
    690   5194   johnz  *   -----------------------------
    691   5194   johnz  * E | esa signature length      |
    692   5194   johnz  *   -----------------------------
    693   5194   johnz  * F | esa signature =           |
    694   5194   johnz  *   |   RSA(HASH(A||B)          |
    695   5194   johnz  *   -----------------------------
    696   5194   johnz  * (lengths are in the same endianness as the original object)
    697   5194   johnz  *
    698   5194   johnz  * cmd_info.ess set for the main binary is correct here, since this
    699   5194   johnz  * is the only elf object we are actually dealing with during the .esa
    700   5194   johnz  * generation.
    701   5194   johnz  */
    702   5194   johnz static ret_t
    703   5194   johnz do_gen_esa(char *object)
    704   5194   johnz {
    705   5194   johnz 	ret_t	ret;
    706   5194   johnz 
    707   5194   johnz 	/* variables used for signing and writing to .esa file */
    708   5194   johnz 	char	*elfobj_esa;
    709   5194   johnz 	size_t	elfobj_esa_len;
    710   5194   johnz 	int	esa_fd;
    711   5194   johnz 	mode_t	mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
    712   5194   johnz 	uchar_t	*esa_buf = NULL;
    713   5194   johnz 	size_t	esa_buf_len = 0;
    714   5194   johnz 	uchar_t hash[SIG_MAX_LENGTH], *hash_ptr = hash;
    715   5194   johnz 	size_t  hash_len = SIG_MAX_LENGTH;
    716   5194   johnz 	uchar_t	esa_sig[SIG_MAX_LENGTH];
    717   5194   johnz 	size_t	esa_sig_len = SIG_MAX_LENGTH;
    718   5194   johnz 	struct filesignatures *fssp = NULL;
    719   5194   johnz 	size_t fslen;
    720   5194   johnz 	ELFCert_t cert = NULL;
    721   5194   johnz 	char *dn;
    722   5194   johnz 	size_t dn_len;
    723   5194   johnz 	uchar_t tmp_buf[sizeof (uint32_t)];
    724   5194   johnz 	int realerrno = 0;
    725   5194   johnz 
    726   5194   johnz 	/*
    727   5194   johnz 	 * variables used for finding information on signer of main
    728   5194   johnz 	 * elfobject.
    729   5194   johnz 	 */
    730   5194   johnz 	uchar_t	orig_signature[SIG_MAX_LENGTH];
    731   5194   johnz 	size_t	orig_sig_len = sizeof (orig_signature);
    732   5194   johnz 
    733   5194   johnz 	cryptodebug("do_gen_esa");
    734   5194   johnz 	if ((ret = getelfobj(object)) != EXIT_OKAY)
    735   5194   johnz 		return (ret);
    736   5194   johnz 	ret = EXIT_SIGN_FAILED;
    737   5194   johnz 
    738  10671    John 	if (cmd_info.token_label &&
    739  10671    John 	    !elfcertlib_settoken(cmd_info.ess, cmd_info.token_label)) {
    740  10671    John 		es_error(gettext("Unable to access token: %s"),
    741  10671    John 		    cmd_info.token_label);
    742  10671    John 		ret = EXIT_SIGN_FAILED;
    743  10671    John 		goto clean_esa;
    744  10671    John 	}
    745  10671    John 
    746  10671    John 	if ((ret = setcertpath()) != EXIT_OKAY)
    747  10671    John 		goto clean_esa;
    748  10671    John 
    749   5194   johnz 	/*
    750   5194   johnz 	 * Find the certificate we need to sign the activation file with.
    751   5194   johnz 	 */
    752   5194   johnz 	if (!elfcertlib_getcert(cmd_info.ess, cmd_info.cert, NULL, &cert,
    753   5194   johnz 	    cmd_info.es_action)) {
    754   5194   johnz 		es_error(gettext("Unable to load certificate: %s"),
    755   5194   johnz 		    cmd_info.cert);
    756   5194   johnz 		ret = EXIT_BAD_CERT;
    757   5194   johnz 		goto clean_esa;
    758   5194   johnz 	}
    759   5194   johnz 
    760   5194   johnz 	if (cmd_info.privpath != NULL) {
    761   5194   johnz 		if (!elfcertlib_loadprivatekey(cmd_info.ess, cert,
    762   5194   johnz 		    cmd_info.privpath)) {
    763   5194   johnz 			es_error(gettext("Unable to load private key: %s"),
    764   5194   johnz 			    cmd_info.privpath);
    765   5194   johnz 			ret = EXIT_BAD_PRIVATEKEY;
    766   5194   johnz 			goto clean_esa;
    767   5194   johnz 		}
    768   5194   johnz 	} else {
    769   5194   johnz 		char *pin = getpin();
    770   5194   johnz 
    771   5194   johnz 		if (pin == NULL) {
    772   5194   johnz 			cryptoerror(LOG_STDERR, gettext("Unable to get PIN"));
    773   5194   johnz 			ret = EXIT_BAD_PRIVATEKEY;
    774   5194   johnz 			goto clean_esa;
    775   5194   johnz 		}
    776   5194   johnz 		if (!elfcertlib_loadtokenkey(cmd_info.ess, cert,
    777   5194   johnz 		    cmd_info.token_label, pin)) {
    778   5194   johnz 			es_error(gettext("Unable to access private key "
    779   5194   johnz 			    "in token %s"), cmd_info.token_label);
    780   5194   johnz 			ret = EXIT_BAD_PRIVATEKEY;
    781   5194   johnz 			goto clean_esa;
    782   5194   johnz 		}
    783   5194   johnz 	}
    784   5194   johnz 
    785   5194   johnz 	/*
    786   5194   johnz 	 * Get the DN from the certificate.
    787   5194   johnz 	 */
    788   5194   johnz 	if ((dn = elfcertlib_getdn(cert)) == NULL) {
    789   5194   johnz 		es_error(gettext("Unable to find DN in certifiate %s"),
    790   5194   johnz 		    cmd_info.cert);
    791   5194   johnz 		goto clean_esa;
    792   5194   johnz 	}
    793   5194   johnz 	dn_len = strlen(dn);
    794   5194   johnz 	cryptodebug("DN = %s", dn);
    795   5194   johnz 
    796   5194   johnz 	/*
    797   5194   johnz 	 * Make sure they are not trying to sign .esa file with a
    798   5194   johnz 	 * limited certificate.
    799   5194   johnz 	 */
    800   5194   johnz 	if (strstr(dn, USAGELIMITED) != NULL) {
    801   5194   johnz 		es_error(gettext("Activation file must be signed with a "
    802   5194   johnz 		    "certficate without %s."), USAGELIMITED);
    803   5194   johnz 		goto clean_esa;
    804   5194   johnz 	}
    805   5194   johnz 
    806   5194   johnz 	/*
    807   5194   johnz 	 * Find information in the associated elfobject that will
    808   5194   johnz 	 * be needed to generate the activation file.
    809   5194   johnz 	 */
    810   5194   johnz 	if (elfsign_signatures(cmd_info.ess, &fssp, &fslen, ES_GET) !=
    811   5194   johnz 	    ELFSIGN_SUCCESS) {
    812   5194   johnz 		es_error(gettext("%s must be signed first, before an "
    813   5194   johnz 		    "associated activation file can be created."),
    814   5194   johnz 		    object);
    815   5194   johnz 		goto clean_esa;
    816   5194   johnz 	}
    817   5194   johnz 	if (elfsign_extract_sig(cmd_info.ess, fssp,
    818   5194   johnz 	    orig_signature, &orig_sig_len) == FILESIG_UNKNOWN) {
    819   5194   johnz 		es_error(gettext("elfsign can not create "
    820   5194   johnz 		    "an associated activation file for the "
    821   5194   johnz 		    "signature format of %s."),
    822   5194   johnz 		    object);
    823   5194   johnz 		goto clean_esa;
    824   5194   johnz 	}
    825   5194   johnz 	{ /* DEBUG START */
    826   5194   johnz 		const int sigstr_len = orig_sig_len * 2 + 1;
    827   5194   johnz 		char *sigstr = malloc(sigstr_len);
    828   5194   johnz 
    829   5194   johnz 		tohexstr(orig_signature, orig_sig_len, sigstr, sigstr_len);
    830   5194   johnz 		cryptodebug("signature value is: %s", sigstr);
    831   5194   johnz 		cryptodebug("sig size value is: %d", orig_sig_len);
    832   5194   johnz 		free(sigstr);
    833   5194   johnz 	} /* DEBUG END */
    834   5194   johnz 
    835   5194   johnz 	esa_buf_len = sizeof (uint32_t) + orig_sig_len;
    836   5194   johnz 	esa_buf = malloc(esa_buf_len);
    837   5194   johnz 	if (esa_buf == NULL) {
    838   5194   johnz 		es_error(gettext("Unable to allocate memory for .esa buffer"));
    839   5194   johnz 		goto clean_esa;
    840   5194   johnz 	}
    841   5194   johnz 
    842   5194   johnz 	/*
    843   5194   johnz 	 * Write eventual contents of .esa file to a temporary
    844   5194   johnz 	 * buffer, so we can sign it before writing out to
    845   5194   johnz 	 * the file.
    846   5194   johnz 	 */
    847   5194   johnz 	elfsign_buffer_len(cmd_info.ess, &orig_sig_len, esa_buf, ES_UPDATE);
    848   5194   johnz 	(void) memcpy(esa_buf + sizeof (uint32_t), orig_signature,
    849   5194   johnz 	    orig_sig_len);
    850   5194   johnz 
    851   5194   johnz 	if (elfsign_hash_esa(cmd_info.ess, esa_buf, esa_buf_len,
    852   5194   johnz 	    &hash_ptr, &hash_len) != ELFSIGN_SUCCESS) {
    853   5194   johnz 		es_error(gettext("Unable to calculate activation hash"));
    854   5194   johnz 		goto clean_esa;
    855   5194   johnz 	}
    856   5194   johnz 
    857   5194   johnz 	/*
    858   5194   johnz 	 * sign the buffer for the .esa file
    859   5194   johnz 	 */
    860   5194   johnz 	if (!elfcertlib_sign(cmd_info.ess, cert,
    861   5194   johnz 	    hash_ptr, hash_len, esa_sig, &esa_sig_len)) {
    862   5194   johnz 		es_error(gettext("Unable to sign .esa data using key from %s"),
    863   5194   johnz 		    cmd_info.privpath ?
    864   5194   johnz 		    cmd_info.privpath : cmd_info.token_label);
    865   5194   johnz 		goto clean_esa;
    866   5194   johnz 	}
    867   5194   johnz 
    868   5194   johnz 	{ /* DEBUG START */
    869   5194   johnz 		const int sigstr_len = esa_sig_len * 2 + 1;
    870   5194   johnz 		char *sigstr = malloc(sigstr_len);
    871   5194   johnz 
    872   5194   johnz 		tohexstr(esa_sig, esa_sig_len, sigstr, sigstr_len);
    873   5194   johnz 		cryptodebug("esa signature value is: %s", sigstr);
    874   5194   johnz 		cryptodebug("esa size value is: %d", esa_sig_len);
    875   5194   johnz 		free(sigstr);
    876   5194   johnz 	} /* DEBUG END */
    877   5194   johnz 
    878   5194   johnz 	/*
    879   5194   johnz 	 * Create the empty activation file once we know
    880   5194   johnz 	 * we are working with the good data.
    881   5194   johnz 	 */
    882   5194   johnz 	elfobj_esa_len = strlen(object) + ESA_LEN + 1;
    883   5194   johnz 	elfobj_esa = malloc(elfobj_esa_len);
    884   5194   johnz 
    885   5194   johnz 	if (elfobj_esa == NULL) {
    886   5194   johnz 		es_error(gettext("Unable to allocate buffer for esa filename"));
    887   5194   johnz 		goto clean_esa;
    888   5194   johnz 	}
    889   5194   johnz 
    890   5194   johnz 	(void) strlcpy(elfobj_esa, object, elfobj_esa_len);
    891   5194   johnz 	(void) strlcat(elfobj_esa, ESA, elfobj_esa_len);
    892   5194   johnz 
    893   5194   johnz 	cryptodebug("Creating .esa file: %s", elfobj_esa);
    894   5194   johnz 
    895   5194   johnz 	if ((esa_fd = open(elfobj_esa, O_WRONLY|O_CREAT|O_EXCL, mode)) == -1) {
    896   5194   johnz 		ESA_ERROR("Unable to create activation file: %s. %s.",
    897   5194   johnz 		    elfobj_esa);
    898   5194   johnz 	}
    899   5194   johnz 
    900   5194   johnz 	if (write(esa_fd, esa_buf, esa_buf_len) != esa_buf_len) {
    901   5194   johnz 		ESA_ERROR("Unable to write contents to %s. %s.",
    902   5194   johnz 		    elfobj_esa);
    903   5194   johnz 	}
    904   5194   johnz 
    905   5194   johnz 	{ /* DEBUG START */
    906   5194   johnz 		const int sigstr_len = dn_len * 2 + 1;
    907   5194   johnz 		char *sigstr = malloc(sigstr_len);
    908   5194   johnz 
    909   5194   johnz 		tohexstr((uchar_t *)dn, dn_len, sigstr, sigstr_len);
    910   5194   johnz 		cryptodebug("dn value is: %s", sigstr);
    911   5194   johnz 		cryptodebug("dn size value is: %d", dn_len);
    912   5194   johnz 		free(sigstr);
    913   5194   johnz 	} /* DEBUG END */
    914   5194   johnz 
    915   5194   johnz 	elfsign_buffer_len(cmd_info.ess, &dn_len, tmp_buf, ES_UPDATE);
    916   5194   johnz 	if (write(esa_fd, tmp_buf, sizeof (tmp_buf)) != sizeof (tmp_buf)) {
    917   5194   johnz 		ESA_ERROR("Unable to write dn_len to %s. %s.", elfobj_esa);
    918   5194   johnz 	}
    919   5194   johnz 
    920   5194   johnz 	if (write(esa_fd, dn, dn_len) != dn_len) {
    921   5194   johnz 		ESA_ERROR("Unable to write dn to %s. %s.", elfobj_esa);
    922   5194   johnz 	}
    923   5194   johnz 
    924   5194   johnz 	elfsign_buffer_len(cmd_info.ess, &esa_sig_len, tmp_buf, ES_UPDATE);
    925   5194   johnz 	if (write(esa_fd, tmp_buf, sizeof (tmp_buf)) != sizeof (tmp_buf)) {
    926   5194   johnz 		ESA_ERROR("Unable to write .esa signature len to %s. %s.",
    927   5194   johnz 		    elfobj_esa);
    928   5194   johnz 	}
    929   5194   johnz 
    930   5194   johnz 	if (write(esa_fd, esa_sig, esa_sig_len) != esa_sig_len) {
    931   5194   johnz 		realerrno = errno;
    932   5194   johnz 		es_error(gettext("Unable to write .esa signature. %s."),
    933   5194   johnz 		    strerror(realerrno));
    934   5194   johnz 		goto clean_esa;
    935   5194   johnz 	}
    936   5194   johnz 
    937   5194   johnz 	ret = EXIT_OKAY;
    938   5194   johnz 
    939   5194   johnz clean_esa:
    940   5194   johnz 	free(fssp);
    941   5194   johnz 	if (esa_fd != -1)
    942   5194   johnz 		(void) close(esa_fd);
    943   5194   johnz 
    944   5194   johnz 	if (esa_buf != NULL)
    945   5194   johnz 		free(esa_buf);
    946   5194   johnz 
    947   5194   johnz 	bzero(esa_sig, esa_sig_len);
    948   5194   johnz 
    949   5194   johnz 	if (cert != NULL)
    950   5194   johnz 		elfcertlib_releasecert(cmd_info.ess, cert);
    951   5194   johnz 	if (cmd_info.ess != NULL)
    952   5194   johnz 		elfsign_end(cmd_info.ess);
    953   5194   johnz 
    954   5194   johnz 	return (ret);
    955   5194   johnz }
    956   5194   johnz 
    957   5194   johnz /*
    958   5194   johnz  * Verify the signature of the object
    959   5194   johnz  * This subcommand is intended to be used by developers during their build
    960   5194   johnz  * processes.  Therefore we can not assume that the certificate is in
    961   5194   johnz  * /etc/crypto/certs so we must use the path we got from the commandline.
    962   5194   johnz  */
    963   5194   johnz static ret_t
    964   5194   johnz do_verify(char *object)
    965   5194   johnz {
    966   5194   johnz 	ELFsign_status_t res;
    967   5194   johnz 	struct ELFsign_sig_info	*esip;
    968   5194   johnz 	ret_t	retval;
    969   5194   johnz 
    970   5194   johnz 	cryptodebug("do_verify");
    971   5194   johnz 	if ((retval = getelfobj(object)) != EXIT_OKAY)
    972   5194   johnz 		return (retval);
    973   5194   johnz 
    974   5194   johnz 	if ((retval = setcertpath()) != EXIT_OKAY) {
    975   5194   johnz 		elfsign_end(cmd_info.ess);
    976   5194   johnz 		return (retval);
    977   5194   johnz 	}
    978   5194   johnz 
    979   5194   johnz 	res = elfsign_verify_signature(cmd_info.ess, &esip);
    980   5194   johnz 	switch (res) {
    981   5194   johnz 	case ELFSIGN_SUCCESS:
    982   5194   johnz 		(void) fprintf(stdout,
    983   5194   johnz 		    gettext("elfsign: verification of %s passed.\n"),
    984   5194   johnz 		    object);
    985   5194   johnz 		if (cmd_info.verbose)
    986   5194   johnz 			sig_info_print(esip);
    987   5194   johnz 		retval = EXIT_OKAY;
    988   5194   johnz 		break;
    989   5194   johnz 	case ELFSIGN_RESTRICTED:
    990   5194   johnz 		(void) fprintf(stdout,
    991   5194   johnz 		    gettext("elfsign: verification of %s passed, "
    992   5194   johnz 		    "but restricted.\n"), object);
    993   5194   johnz 		if (cmd_info.verbose)
    994   5194   johnz 			sig_info_print(esip);
    995   5194   johnz 		retval = EXIT_OKAY;
    996   5194   johnz 		break;
    997   5194   johnz 	case ELFSIGN_FAILED:
    998   5194   johnz 	case ELFSIGN_INVALID_CERTPATH:
    999   5194   johnz 		es_error(gettext("verification of %s failed."),
   1000   5194   johnz 		    object);
   1001   5194   johnz 		if (cmd_info.verbose)
   1002   5194   johnz 			sig_info_print(esip);
   1003   5194   johnz 		retval = EXIT_VERIFY_FAILED;
   1004   5194   johnz 		break;
   1005   5194   johnz 	case ELFSIGN_NOTSIGNED:
   1006   5194   johnz 		es_error(gettext("no signature found in %s."),
   1007   5194   johnz 		    object);
   1008   5194   johnz 		retval = EXIT_VERIFY_FAILED_UNSIGNED;
   1009   5194   johnz 		break;
   1010   5194   johnz 	default:
   1011   5194   johnz 		es_error(gettext("unexpected failure attempting verification "
   1012   5194   johnz 		    "of %s."), object);
   1013   5194   johnz 		retval = EXIT_VERIFY_FAILED_UNSIGNED;
   1014   5194   johnz 		break;
   1015   5194   johnz 	}
   1016   5194   johnz 
   1017   5194   johnz 	if (esip != NULL)
   1018   5194   johnz 		elfsign_sig_info_free(esip);
   1019   5194   johnz 	if (cmd_info.ess != NULL)
   1020   5194   johnz 		elfsign_end(cmd_info.ess);
   1021   5194   johnz 	return (retval);
   1022   5194   johnz }
   1023   5194   johnz 
   1024   5194   johnz #define	SET_VALUE(f, s) \
   1025   5194   johnz 	kmfrv = f; \
   1026   5194   johnz 	if (kmfrv != KMF_OK) { \
   1027   5194   johnz 		char *e = NULL; \
   1028  10671    John 		(void) kmf_get_kmf_error_str(kmfrv, &e); \
   1029   5194   johnz 		cryptoerror(LOG_STDERR, \
   1030   5194   johnz 			gettext("Failed to %s: %s\n"), \
   1031   5194   johnz 			s, (e ? e : "unknown error")); \
   1032   5194   johnz 		if (e) free(e); \
   1033   5194   johnz 		goto cleanup; \
   1034   5194   johnz 	}
   1035   5194   johnz 
   1036   5194   johnz static KMF_RETURN
   1037   5194   johnz create_csr(char *dn)
   1038   5194   johnz {
   1039   5194   johnz 	KMF_RETURN kmfrv = KMF_OK;
   1040   5194   johnz 	KMF_HANDLE_T kmfhandle = NULL;
   1041   5194   johnz 	KMF_KEY_HANDLE pubk, prik;
   1042   5194   johnz 	KMF_X509_NAME csrSubject;
   1043   5194   johnz 	KMF_CSR_DATA csr;
   1044   5194   johnz 	KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA;
   1045   5194   johnz 	KMF_DATA signedCsr = { NULL, 0 };
   1046   5194   johnz 	char *err;
   1047  10671    John 	KMF_ATTRIBUTE	attrlist[16];
   1048  10671    John 	KMF_ENCODE_FORMAT	format;
   1049  10671    John 	KMF_KEYSTORE_TYPE	kstype;
   1050  10671    John 	KMF_KEY_ALG	keytype;
   1051  10671    John 	uint32_t	keylength;
   1052  10671    John 	KMF_CREDENTIAL	cred;
   1053  10671    John 	char	*pin = NULL;
   1054  10671    John 	int	numattr;
   1055   5194   johnz 
   1056  10671    John 	if ((kmfrv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
   1057  10671    John 		(void) kmf_get_kmf_error_str(kmfrv, &err);
   1058   5194   johnz 		cryptoerror(LOG_STDERR,
   1059   5194   johnz 		    gettext("Error initializing KMF: %s\n"),
   1060   5194   johnz 		    (err ? err : "unknown error"));
   1061   5194   johnz 		if (err)
   1062   5194   johnz 			free(err);
   1063   5194   johnz 		return (kmfrv);
   1064   5194   johnz 	}
   1065   5194   johnz 	(void) memset(&csr, 0, sizeof (csr));
   1066   5194   johnz 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
   1067   5194   johnz 
   1068   5194   johnz 	if (cmd_info.privpath != NULL) {
   1069  10671    John 		kstype = KMF_KEYSTORE_OPENSSL;
   1070  10671    John 		format = KMF_FORMAT_ASN1;
   1071  10671    John 	} else {
   1072  10671    John 		boolean_t	readonly;
   1073  10671    John 		/* args checking verified (cmd_info.token_label != NULL) */
   1074   5194   johnz 
   1075   5194   johnz 		/* Get a PIN to store the private key in the token */
   1076  10671    John 		pin = getpin();
   1077   5194   johnz 
   1078   5194   johnz 		if (pin == NULL) {
   1079  10671    John 			(void) kmf_finalize(kmfhandle);
   1080   5194   johnz 			return (KMF_ERR_AUTH_FAILED);
   1081   5194   johnz 		}
   1082   5194   johnz 
   1083  10671    John 		kstype = KMF_KEYSTORE_PK11TOKEN;
   1084  10671    John 		readonly = B_FALSE;
   1085   5194   johnz 
   1086  10671    John 		numattr = 0;
   1087  10671    John 		kmf_set_attr_at_index(attrlist, numattr++,
   1088  10671    John 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
   1089  10671    John 		kmf_set_attr_at_index(attrlist, numattr++,
   1090  10671    John 		    KMF_TOKEN_LABEL_ATTR, cmd_info.token_label,
   1091  10671    John 		    strlen(cmd_info.token_label));
   1092  10671    John 		kmf_set_attr_at_index(attrlist, numattr++,
   1093  10671    John 		    KMF_READONLY_ATTR, &readonly, sizeof (readonly));
   1094  10671    John 		kmfrv = kmf_configure_keystore(kmfhandle, numattr, attrlist);
   1095   5194   johnz 		if (kmfrv != KMF_OK) {
   1096   5194   johnz 			goto cleanup;
   1097   5194   johnz 		}
   1098   5194   johnz 	}
   1099   5194   johnz 
   1100   5194   johnz 	/* Create the RSA keypair */
   1101  10671    John 	keytype = KMF_RSA;
   1102  10671    John 	keylength = ES_DEFAULT_KEYSIZE;
   1103  10671    John 	(void) memset(&prik, 0, sizeof (prik));
   1104  10671    John 	(void) memset(&pubk, 0, sizeof (pubk));
   1105   5194   johnz 
   1106  10671    John 	numattr = 0;
   1107  10671    John 	kmf_set_attr_at_index(attrlist, numattr++,
   1108  10671    John 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
   1109  10671    John 	kmf_set_attr_at_index(attrlist, numattr++,
   1110  10671    John 	    KMF_KEYALG_ATTR, &keytype, sizeof (keytype));
   1111  10671    John 	kmf_set_attr_at_index(attrlist, numattr++,
   1112  10671    John 	    KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength));
   1113  10671    John 	if (pin != NULL) {
   1114  10671    John 		cred.cred = pin;
   1115  10671    John 		cred.credlen = strlen(pin);
   1116  10671    John 		kmf_set_attr_at_index(attrlist, numattr++,
   1117  10671    John 		    KMF_CREDENTIAL_ATTR, &cred, sizeof (KMF_CREDENTIAL));
   1118  10671    John 	}
   1119  10671    John 	kmf_set_attr_at_index(attrlist, numattr++,
   1120  10671    John 	    KMF_PRIVKEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
   1121  10671    John 	kmf_set_attr_at_index(attrlist, numattr++,
   1122  10671    John 	    KMF_PUBKEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE));
   1123  10671    John 	if (kstype == KMF_KEYSTORE_OPENSSL) {
   1124  10671    John 		kmf_set_attr_at_index(attrlist, numattr++,
   1125  10671    John 		    KMF_KEY_FILENAME_ATTR, cmd_info.privpath,
   1126  10671    John 		    strlen(cmd_info.privpath));
   1127  10671    John 		kmf_set_attr_at_index(attrlist, numattr++,
   1128  10671    John 		    KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format));
   1129  10671    John 	}
   1130  10671    John 
   1131  10671    John 	kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist);
   1132   5194   johnz 	if (kmfrv != KMF_OK) {
   1133  10671    John 		(void) kmf_get_kmf_error_str(kmfrv, &err);
   1134  10671    John 		cryptoerror(LOG_STDERR,
   1135  10671    John 		    gettext("Create RSA keypair failed: %s"),
   1136  10671    John 		    (err ? err : "unknown error"));
   1137  10671    John 		free(err);
   1138   5194   johnz 		goto cleanup;
   1139   5194   johnz 	}
   1140   5194   johnz 
   1141  10671    John 	kmfrv = kmf_dn_parser(dn, &csrSubject);
   1142   5194   johnz 	if (kmfrv != KMF_OK) {
   1143  10671    John 		(void) kmf_get_kmf_error_str(kmfrv, &err);
   1144  10671    John 		cryptoerror(LOG_STDERR,
   1145  10671    John 		    gettext("Error parsing subject name: %s\n"),
   1146  10671    John 		    (err ? err : "unknown error"));
   1147  10671    John 		free(err);
   1148   5194   johnz 		goto cleanup;
   1149   5194   johnz 	}
   1150   5194   johnz 
   1151  10671    John 	SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair");
   1152   5194   johnz 
   1153  10671    John 	SET_VALUE(kmf_set_csr_version(&csr, 2), "version number");
   1154   5194   johnz 
   1155  10671    John 	SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name");
   1156   5194   johnz 
   1157  10671    John 	SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "SignatureAlgorithm");
   1158   5194   johnz 
   1159  10671    John 	if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) ==
   1160   5194   johnz 	    KMF_OK) {
   1161  10671    John 		kmfrv = kmf_create_csr_file(&signedCsr, KMF_FORMAT_PEM,
   1162   5194   johnz 		    cmd_info.cert);
   1163   5194   johnz 	}
   1164   5194   johnz 
   1165   5194   johnz cleanup:
   1166  10671    John 	(void) kmf_free_kmf_key(kmfhandle, &prik);
   1167  10671    John 	(void) kmf_free_data(&signedCsr);
   1168  10671    John 	(void) kmf_free_signed_csr(&csr);
   1169  10671    John 	(void) kmf_finalize(kmfhandle);
   1170   5194   johnz 
   1171   5194   johnz 	return (kmfrv);
   1172   5194   johnz }
   1173   5194   johnz 
   1174   5194   johnz static boolean_t
   1175   5194   johnz is_restricted(void)
   1176   5194   johnz {
   1177   5194   johnz 	char	nr[80]; /* Non-retail provider? big buffer for l10n */
   1178   5194   johnz 	char	*yeschar = nl_langinfo(YESSTR);
   1179   5194   johnz 	char	*nochar = nl_langinfo(NOSTR);
   1180   5194   johnz 
   1181   5194   johnz 	/*
   1182   5194   johnz 	 * Find out if user will need an activation file.
   1183   5194   johnz 	 * These questions cover cases #1 and #2 from the Jumbo Export
   1184   5194   johnz 	 * Control case.  The logic of these questions should not be modified
   1185   5194   johnz 	 * without consulting the jumbo case, unless there is a new
   1186   5194   johnz 	 * export case or a change in export/import regulations for Sun
   1187   5194   johnz 	 * and Sun customers.
   1188   5194   johnz 	 * Case #3 should be covered in the developer documentation.
   1189   5194   johnz 	 */
   1190   5194   johnz /* BEGIN CSTYLED */
   1191   5194   johnz 	(void) fprintf(stdout, gettext("\n"
   1192   5194   johnz "The government of the United States of America restricts the export of \n"
   1193   5194   johnz "\"open cryptographic interfaces\", also known as \"crypto-with-a-hole\".\n"
   1194   5194   johnz "Due to this restriction, all providers for the Solaris cryptographic\n"
   1195   5194   johnz "framework must be signed, regardless of the country of origin.\n\n"));
   1196   5194   johnz 
   1197   5194   johnz 	(void) fprintf(stdout, gettext(
   1198   5194   johnz "The terms \"retail\" and \"non-retail\" refer to export classifications \n"
   1199   5194   johnz "for products manufactured in the USA.  These terms define the portion of the\n"
   1200   5194   johnz "world where the product may be shipped.  Roughly speaking, \"retail\" is \n"
   1201   5194   johnz "worldwide (minus certain excluded nations) and \"non-retail\" is domestic \n"
   1202   5194   johnz "only (plus some highly favored nations).  If your provider is subject to\n"
   1203   5194   johnz "USA export control, then you must obtain an export approval (classification)\n"
   1204   5194   johnz "from the government of the USA before exporting your provider.  It is\n"
   1205   5194   johnz "critical that you specify the obtained (or expected, when used during \n"
   1206   5194   johnz "development) classification to the following questions so that your provider\n"
   1207   5194   johnz "will be appropriately signed.\n\n"));
   1208   5194   johnz 
   1209   5194   johnz 	for (;;) {
   1210   5194   johnz 		(void) fprintf(stdout, gettext(
   1211   5194   johnz "Do you have retail export approval for use without restrictions based \n"
   1212   5194   johnz "on the caller (for example, IPsec)? [Yes/No] "));
   1213   5194   johnz /* END CSTYLED */
   1214   5194   johnz 
   1215   5194   johnz 		(void) fflush(stdout);
   1216   5194   johnz 
   1217   5194   johnz 		(void) fgets(nr, sizeof (nr), stdin);
   1218   5194   johnz 		if (nr == NULL)
   1219   5194   johnz 			goto demand_answer;
   1220   5194   johnz 
   1221   5194   johnz 		nr[strlen(nr) - 1] = '\0';
   1222   5194   johnz 
   1223   5194   johnz 		if (strncasecmp(nochar, nr, 1) == 0) {
   1224   5194   johnz /* BEGIN CSTYLED */
   1225   5194   johnz 			(void) fprintf(stdout, gettext("\n"
   1226   5194   johnz "If you have non-retail export approval for unrestricted use of your provider\n"
   1227   5194   johnz "by callers, are you also planning to receive retail approval by restricting \n"
   1228   5194   johnz "which export sensitive callers (for example, IPsec) may use your \n"
   1229   5194   johnz "provider? [Yes/No] "));
   1230   5194   johnz /* END CSTYLED */
   1231   5194   johnz 
   1232   5194   johnz 			(void) fflush(stdout);
   1233   5194   johnz 
   1234   5194   johnz 			(void) fgets(nr, sizeof (nr), stdin);
   1235   5194   johnz 
   1236   5194   johnz 			/*
   1237   5194   johnz 			 * flush standard input so any remaining text
   1238   5194   johnz 			 * does not affect next read.
   1239   5194   johnz 			 */
   1240   5194   johnz 			(void) fflush(stdin);
   1241   5194   johnz 
   1242   5194   johnz 			if (nr == NULL)
   1243   5194   johnz 				goto demand_answer;
   1244   5194   johnz 
   1245   5194   johnz 			nr[strlen(nr) - 1] = '\0';
   1246   5194   johnz 
   1247   5194   johnz 			if (strncasecmp(nochar, nr, 1) == 0) {
   1248   5194   johnz 				return (B_FALSE);
   1249   5194   johnz 			} else if (strncasecmp(yeschar, nr, 1) == 0) {
   1250   5194   johnz 				return (B_TRUE);
   1251   5194   johnz 			} else
   1252   5194   johnz 				goto demand_answer;
   1253   5194   johnz 
   1254   5194   johnz 		} else if (strncasecmp(yeschar, nr, 1) == 0) {
   1255   5194   johnz 			return (B_FALSE);
   1256   5194   johnz 		}
   1257   5194   johnz 
   1258   5194   johnz 	demand_answer:
   1259   5194   johnz 		(void) fprintf(stdout,
   1260   5194   johnz 		    gettext("You must specify an answer.\n\n"));
   1261   5194   johnz 	}
   1262   5194   johnz }
   1263   5194   johnz 
   1264   5194   johnz #define	CN_MAX_LENGTH	64	/* Verisign implementation limit */
   1265   5194   johnz /*
   1266   5194   johnz  * Generate a certificate request into the file named cmd_info.cert
   1267   5194   johnz  */
   1268   5194   johnz /*ARGSUSED*/
   1269   5194   johnz static ret_t
   1270   5194   johnz do_cert_request(char *object)
   1271   5194   johnz {
   1272   5194   johnz 	const char	 PartnerDNFMT[] =
   1273   5194   johnz 	    "CN=%s, "
   1274   5194   johnz 	    "OU=Class B, "
   1275   5194   johnz 	    "%sOU=Solaris Cryptographic Framework, "
   1276   5194   johnz 	    "OU=Partner Object Signing, "
   1277   5194   johnz 	    "O=Sun Microsystems Inc";
   1278   5194   johnz 	const char	 SunCDNFMT[] =
   1279   5194   johnz 	    "CN=%s, "
   1280   5194   johnz 	    "OU=Class B, "
   1281   5194   johnz 	    "%sOU=Solaris Cryptographic Framework, "
   1282   5194   johnz 	    "OU=Corporate Object Signing, "
   1283   5194   johnz 	    "O=Sun Microsystems Inc";
   1284   5194   johnz 	const char	 SunSDNFMT[] =
   1285   5194   johnz 	    "CN=%s, "
   1286   5194   johnz 	    "OU=Class B, "
   1287   5194   johnz 	    "%sOU=Solaris Signed Execution, "
   1288   5194   johnz 	    "OU=Corporate Object Signing, "
   1289   5194   johnz 	    "O=Sun Microsystems Inc";
   1290   5194   johnz 	const char	 *dnfmt = NULL;
   1291   5194   johnz 	char	cn[CN_MAX_LENGTH + 1];
   1292   5194   johnz 	char	*dn = NULL;
   1293   5194   johnz 	size_t	dn_len;
   1294   5194   johnz 	char	*restriction = "";
   1295   5194   johnz 	KMF_RETURN   kmfret;
   1296   5194   johnz 	cryptodebug("do_cert_request");
   1297   5194   johnz 
   1298   5194   johnz 	/*
   1299   5194   johnz 	 * Get the DN prefix from the user
   1300   5194   johnz 	 */
   1301   5194   johnz 	switch (cmd_info.internal_req) {
   1302   5194   johnz 	case 'c':
   1303   5194   johnz 		dnfmt = SunCDNFMT;
   1304   5194   johnz 		(void) fprintf(stdout, gettext(
   1305   5194   johnz 		    "Enter Sun Microsystems, Inc. Release name.\n"
   1306   5194   johnz 		    "This will be the prefix of the Certificate DN: "));
   1307   5194   johnz 		break;
   1308   5194   johnz 	case 's':
   1309   5194   johnz 		dnfmt = SunSDNFMT;
   1310   5194   johnz 		(void) fprintf(stdout, gettext(
   1311   5194   johnz 		    "Enter Sun Microsystems, Inc. Release name.\n"
   1312   5194   johnz 		    "This will be the prefix of the Certificate DN: "));
   1313   5194   johnz 		break;
   1314   5194   johnz 	default:
   1315   5194   johnz 		dnfmt = PartnerDNFMT;
   1316   5194   johnz 		(void) fprintf(stdout, gettext(
   1317   5194   johnz 		    "Enter Company Name / Stock Symbol"
   1318   5194   johnz 		    " or some other globally unique identifier.\n"
   1319   5194   johnz 		    "This will be the prefix of the Certificate DN: "));
   1320   5194   johnz 		break;
   1321   5194   johnz 	}
   1322   5194   johnz 
   1323   5194   johnz 	(void) fgets(cn, sizeof (cn), stdin);
   1324   5194   johnz 	if ((cn == NULL) || (cn[0] == '\n')) {
   1325   5194   johnz 		es_error(gettext("you must specify a Certificate DN prefix"));
   1326   5194   johnz 		return (EXIT_INVALID_ARG);
   1327   5194   johnz 	}
   1328   5194   johnz 
   1329   5194   johnz 	if (cn[strlen(cn) - 1] == '\n') {
   1330   5194   johnz 		cn[strlen(cn) - 1] = '\0';	/* chop trailing \n */
   1331   5194   johnz 	} else {
   1332   5194   johnz 		es_error(gettext("You must specify a Certificate DN prefix "
   1333   5194   johnz 		    "of no more than %d characters"), CN_MAX_LENGTH);
   1334   5194   johnz 		return (EXIT_INVALID_ARG);
   1335   5194   johnz 	}
   1336   5194   johnz 
   1337   5194   johnz 	/*
   1338   5194   johnz 	 * determine if there is an export restriction
   1339   5194   johnz 	 */
   1340   5194   johnz 	switch (cmd_info.internal_req) {
   1341   5194   johnz 	case 's':
   1342   5194   johnz 		restriction = "";
   1343   5194   johnz 		break;
   1344   5194   johnz 	default:
   1345   5194   johnz 		restriction = is_restricted() ? USAGELIMITED ", " : "";
   1346   5194   johnz 		break;
   1347   5194   johnz 	}
   1348   5194   johnz 
   1349   5194   johnz 	/* Update DN string */
   1350   5194   johnz 	dn_len = strlen(cn) + strlen(dnfmt) + strlen(restriction);
   1351   5194   johnz 	dn = malloc(dn_len + 1);
   1352   5194   johnz 	(void) snprintf(dn, dn_len, dnfmt, cn, restriction);
   1353   5194   johnz 
   1354   5194   johnz 	cryptodebug("Generating Certificate request for DN: %s", dn);
   1355   5194   johnz 	kmfret = create_csr(dn);
   1356   5194   johnz 	free(dn);
   1357   5194   johnz 	if (kmfret == KMF_OK)
   1358   5194   johnz 		return (EXIT_OKAY);
   1359   5194   johnz 	else
   1360   5194   johnz 		return (EXIT_CSR_FAILED);
   1361   5194   johnz }
   1362   5194   johnz 
   1363   5194   johnz static void
   1364   5194   johnz str_print(char *s)
   1365   5194   johnz {
   1366   5194   johnz 	if (s == NULL)
   1367   5194   johnz 		return;
   1368   5194   johnz 	(void) fprintf(stdout, "%s\n", s);
   1369   5194   johnz }
   1370   5194   johnz 
   1371   5194   johnz /*ARGSUSED*/
   1372   5194   johnz static ret_t
   1373   5194   johnz do_list(char *object)
   1374   5194   johnz {
   1375   5194   johnz 	ret_t	retval;
   1376   5194   johnz 
   1377   5194   johnz 	if (cmd_info.elfcnt > 0) {
   1378   5194   johnz 		ELFsign_status_t	elfstat;
   1379   5194   johnz 		struct filesignatures	*fssp = NULL;
   1380   5194   johnz 		size_t fs_len;
   1381   5194   johnz 		struct ELFsign_sig_info	*esip;
   1382   5194   johnz 
   1383   5194   johnz 		if ((retval = getelfobj(cmd_info.elfobj[0])) != EXIT_OKAY)
   1384   5194   johnz 			return (retval);
   1385   5194   johnz 		elfstat = elfsign_signatures(cmd_info.ess,
   1386   5194   johnz 		    &fssp, &fs_len, ES_GET);
   1387   5194   johnz 		if (elfstat == ELFSIGN_SUCCESS) {
   1388   5194   johnz 			retval = EXIT_OKAY;
   1389   5194   johnz 			if (elfsign_sig_info(fssp, &esip)) {
   1390   5194   johnz 				switch (cmd_info.field) {
   1391   5194   johnz 				case FLD_FORMAT:
   1392   5194   johnz 					str_print(esip->esi_format);
   1393   5194   johnz 					break;
   1394   5194   johnz 				case FLD_SIGNER:
   1395   5194   johnz 					str_print(esip->esi_signer);
   1396   5194   johnz 					break;
   1397   5194   johnz 				case FLD_TIME:
   1398   5194   johnz 					if (esip->esi_time == 0)
   1399   5194   johnz 						retval = EXIT_INVALID_ARG;
   1400   5194   johnz 					else
   1401   5194   johnz 						str_print(time_str(
   1402   5194   johnz 						    esip->esi_time));
   1403   5194   johnz 					break;
   1404   5194   johnz 				default:
   1405   5194   johnz 					retval = EXIT_INVALID_ARG;
   1406   5194   johnz 				}
   1407   5194   johnz 				elfsign_sig_info_free(esip);
   1408   5194   johnz 			}
   1409   5194   johnz 			free(fssp);
   1410   5194   johnz 		} else
   1411   5194   johnz 			retval = EXIT_VERIFY_FAILED_UNSIGNED;
   1412   5194   johnz 		elfsign_end(cmd_info.ess);
   1413   5194   johnz 	} else {
   1414   5194   johnz 		ELFCert_t	cert;
   1415   5194   johnz 		/*
   1416   5194   johnz 		 * Initialize the ESS record here even though we are not
   1417   5194   johnz 		 * actually opening any ELF files.
   1418   5194   johnz 		 */
   1419   5194   johnz 		if (elfsign_begin(NULL, ES_GET, &(cmd_info.ess)) !=
   1420   5194   johnz 		    ELFSIGN_SUCCESS)
   1421   5194   johnz 			return (EXIT_MEMORY_ERROR);
   1422   5194   johnz 
   1423   5194   johnz 		if (elfcertlib_getcert(cmd_info.ess, cmd_info.cert, NULL,
   1424   5194   johnz 		    &cert, cmd_info.es_action)) {
   1425   5194   johnz 			retval = EXIT_OKAY;
   1426   5194   johnz 			switch (cmd_info.field) {
   1427   5194   johnz 			case FLD_SUBJECT:
   1428   5194   johnz 				str_print(elfcertlib_getdn(cert));
   1429   5194   johnz 				break;
   1430   5194   johnz 			case FLD_ISSUER:
   1431   5194   johnz 				str_print(elfcertlib_getissuer(cert));
   1432   5194   johnz 				break;
   1433   5194   johnz 			default:
   1434   5194   johnz 				retval = EXIT_INVALID_ARG;
   1435   5194   johnz 			}
   1436   5194   johnz 			elfcertlib_releasecert(cmd_info.ess, cert);
   1437   5194   johnz 		} else
   1438   5194   johnz 			retval = EXIT_BAD_CERT;
   1439   5194   johnz 		elfsign_end(cmd_info.ess);
   1440   5194   johnz 	}
   1441   5194   johnz 
   1442   5194   johnz 	return (retval);
   1443   5194   johnz }
   1444   5194   johnz 
   1445   5194   johnz static void
   1446   5194   johnz es_error(const char *fmt, ...)
   1447   5194   johnz {
   1448   5194   johnz 	char msgbuf[BUFSIZ];
   1449   5194   johnz 	va_list	args;
   1450   5194   johnz 
   1451   5194   johnz 	va_start(args, fmt);
   1452   5194   johnz 	(void) vsnprintf(msgbuf, sizeof (msgbuf), fmt, args);
   1453   5194   johnz 	va_end(args);
   1454   5194   johnz 	(void) fflush(stdout);
   1455   5194   johnz 	cryptoerror(LOG_STDERR, "%s", msgbuf);
   1456   5194   johnz 	(void) fflush(stderr);
   1457   5194   johnz }
   1458   5194   johnz 
   1459   5194   johnz static char *
   1460   5194   johnz time_str(time_t t)
   1461   5194   johnz {
   1462   5194   johnz 	static char	buf[80];
   1463   5194   johnz 	char		*bufp;
   1464   5194   johnz 
   1465   5194   johnz 	bufp = buf;
   1466   5194   johnz 	if (strftime(buf, sizeof (buf), NULL, localtime(&t)) == 0)
   1467   5194   johnz 		bufp = ctime(&t);
   1468   5194   johnz 	return (bufp);
   1469   5194   johnz }
   1470   5194   johnz 
   1471   5194   johnz static void
   1472   5194   johnz sig_info_print(struct ELFsign_sig_info *esip)
   1473   5194   johnz {
   1474   5194   johnz 	if (esip == NULL)
   1475   5194   johnz 		return;
   1476   5194   johnz 	(void) fprintf(stdout, gettext("format: %s.\n"), esip->esi_format);
   1477   5194   johnz 	(void) fprintf(stdout, gettext("signer: %s.\n"), esip->esi_signer);
   1478   5194   johnz 	if (esip->esi_time == 0)
   1479   5194   johnz 		return;
   1480   5194   johnz 	(void) fprintf(stdout, gettext("signed on: %s.\n"),
   1481   5194   johnz 	    time_str(esip->esi_time));
   1482   5194   johnz }
   1483