4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Developer command for adding the signature section to an ELF object
31 * This command uses the cryptodebug() function from libcryptoutil.
32 * Set SUNW_CRYPTO_DEBUG to stderr or syslog for all debug to go to auth.debug
41 #include <sys/types.h>
49 #include <cryptoutil.h>
50 #include <sys/crypto/elfsign.h>
51 #include <libelfsign.h>
56 #define SIGN_OPTS "c:e:F:k:P:T:v"
57 #define VERIFY "verify"
58 #define VERIFY_OPTS "c:e:v"
59 #define REQUEST "request"
60 #define REQUEST_OPTS "i:k:r:T:"
62 #define LIST_OPTS "c:e:f:"
80 #define MIN_ARGS 3 /* The minimum # args to do anything */
81 #define ES_DEFAULT_KEYSIZE 1024
84 enum cmd_e cmd
; /* sub command: sign | verify | request */
85 char *cert
; /* -c <certificate_file> | */
86 /* -r <certificate_request_file> */
87 char **elfobj
; /* -e <elf_object> */
89 enum ES_ACTION es_action
;
90 ELFsign_t ess
; /* libelfsign opaque "state" */
92 enum field_e field
; /* -f <field> */
93 char internal_req
; /* Sun internal certificate request */
94 char *pinpath
; /* -P <pin> */
95 char *privpath
; /* -k <private_key> */
96 char *token_label
; /* -T <token_label> */
97 boolean_t verbose
; /* chatty output */
104 EXIT_CANT_OPEN_ELF_OBJECT
,
108 EXIT_VERIFY_FAILED_UNSIGNED
,
117 { "subject", FLD_SUBJECT
},
118 { "issuer", FLD_ISSUER
},
119 { "format", FLD_FORMAT
},
120 { "signer", FLD_SIGNER
},
121 { "time", FLD_TIME
},
125 typedef enum ret_e ret_t
;
127 static void usage(void);
128 static ret_t
getelfobj(char *);
129 static char *getpin(void);
130 static ret_t
do_sign(char *);
131 static ret_t
do_verify(char *);
132 static ret_t
do_cert_request(char *);
133 static ret_t
do_list(char *);
134 static void es_error(const char *fmt
, ...);
135 static char *time_str(time_t t
);
136 static void sig_info_print(struct ELFsign_sig_info
*esip
);
139 main(int argc
, char **argv
)
143 char *opts
; /* The set of flags for cmd */
144 int errflag
= 0; /* We had an options parse error */
145 char c
; /* current getopts flag */
146 ret_t (*action
)(char *); /* Function pointer for the action */
149 (void) setlocale(LC_ALL
, "");
150 #if !defined(TEXT_DOMAIN) /* Should be defiend by cc -D */
151 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
153 (void) textdomain(TEXT_DOMAIN
);
155 cryptodebug_init("elfsign");
157 if (argc
< MIN_ARGS
) {
158 es_error(gettext("invalid number of arguments"));
160 return (EXIT_INVALID_ARG
);
164 cmd_info
.cert
= NULL
;
165 cmd_info
.elfobj
= NULL
;
167 cmd_info
.es_action
= ES_GET
;
169 cmd_info
.extracnt
= 0;
170 cmd_info
.field
= FLD_UNKNOWN
;
171 cmd_info
.internal_req
= '\0';
172 cmd_info
.pinpath
= NULL
;
173 cmd_info
.privpath
= NULL
;
174 cmd_info
.token_label
= NULL
;
175 cmd_info
.verbose
= B_FALSE
;
177 if (strcmp(scmd
, SIGN
) == 0) {
178 cmd_info
.cmd
= ES_SIGN
;
180 cryptodebug("cmd=sign opts=%s", opts
);
182 cmd_info
.es_action
= ES_UPDATE_RSA_SHA1
;
183 } else if (strcmp(scmd
, VERIFY
) == 0) {
184 cmd_info
.cmd
= ES_VERIFY
;
186 cryptodebug("cmd=verify opts=%s", opts
);
188 } else if (strcmp(scmd
, REQUEST
) == 0) {
189 cmd_info
.cmd
= ES_REQUEST
;
191 cryptodebug("cmd=request opts=%s", opts
);
192 action
= do_cert_request
;
193 } else if (strcmp(scmd
, LIST
) == 0) {
194 cmd_info
.cmd
= ES_LIST
;
196 cryptodebug("cmd=list opts=%s", opts
);
199 es_error(gettext("Unknown sub-command: %s"),
202 return (EXIT_INVALID_ARG
);
206 * Note: There is no need to check that optarg isn't NULL
207 * because getopt does that for us.
209 while (!errflag
&& (c
= getopt(argc
- 1, argv
+ 1, opts
)) != EOF
) {
210 if (strchr("ceFihkPTr", c
) != NULL
)
211 cryptodebug("c=%c, '%s'", c
, optarg
);
213 cryptodebug("c=%c", c
);
217 cmd_info
.cert
= optarg
;
221 cmd_info
.elfobj
= reallocarray(cmd_info
.elfobj
,
222 cmd_info
.elfcnt
, sizeof (char *));
223 if (cmd_info
.elfobj
== NULL
) {
225 "Too many elf objects specified."));
226 return (EXIT_INVALID_ARG
);
228 cmd_info
.elfobj
[cmd_info
.elfcnt
- 1] = optarg
;
233 cmd_info
.field
= FLD_UNKNOWN
;
234 for (fp
= fields
; fp
->name
!= NULL
; fp
++) {
235 if (strcasecmp(optarg
, fp
->name
) == 0) {
236 cmd_info
.field
= fp
->field
;
240 if (cmd_info
.field
== FLD_UNKNOWN
) {
241 cryptodebug("Invalid field option");
247 if (strcasecmp(optarg
, ES_FMT_RSA_MD5_SHA1
) == 0)
248 cmd_info
.es_action
= ES_UPDATE_RSA_MD5_SHA1
;
249 else if (strcasecmp(optarg
, ES_FMT_RSA_SHA1
) == 0)
250 cmd_info
.es_action
= ES_UPDATE_RSA_SHA1
;
252 cryptodebug("Invalid format option");
256 case 'i': /* Undocumented internal Sun use only */
257 cmd_info
.internal_req
= *optarg
;
260 cmd_info
.privpath
= optarg
;
261 if (cmd_info
.token_label
!= NULL
||
262 cmd_info
.pinpath
!= NULL
)
266 cmd_info
.pinpath
= optarg
;
267 if (cmd_info
.privpath
!= NULL
)
271 cmd_info
.cert
= optarg
;
274 cmd_info
.token_label
= optarg
;
275 if (cmd_info
.privpath
!= NULL
)
279 cmd_info
.verbose
= B_TRUE
;
286 optind
++; /* we skipped over subcommand */
287 cmd_info
.extracnt
= argc
- optind
;
289 if (cmd_info
.extracnt
!= 0 &&
290 cmd_info
.cmd
!= ES_SIGN
&& cmd_info
.cmd
!= ES_VERIFY
) {
291 cryptodebug("Extra arguments, optind=%d, argc=%d",
296 switch (cmd_info
.cmd
) {
298 if (cmd_info
.elfcnt
+ argc
- optind
== 0) {
299 cryptodebug("Missing elfobj");
305 if (((cmd_info
.privpath
== NULL
) &&
306 (cmd_info
.token_label
== NULL
)) ||
307 (cmd_info
.cert
== NULL
) ||
308 (cmd_info
.elfcnt
+ argc
- optind
== 0)) {
309 cryptodebug("Missing privpath|token_label/cert/elfobj");
315 if (((cmd_info
.privpath
== NULL
) &&
316 (cmd_info
.token_label
== NULL
)) ||
317 (cmd_info
.cert
== NULL
)) {
318 cryptodebug("Missing privpath|token_label/certreq");
323 if ((cmd_info
.cert
!= NULL
) == (cmd_info
.elfcnt
> 0)) {
324 cryptodebug("Neither or both of cert/elfobj");
332 return (EXIT_INVALID_ARG
);
335 switch (cmd_info
.cmd
) {
347 for (i
= 0; i
< cmd_info
.elfcnt
&&
348 (ret
== EXIT_OKAY
|| cmd_info
.cmd
!= ES_SIGN
); i
++) {
349 iret
= action(cmd_info
.elfobj
[i
]);
353 for (i
= optind
; i
< argc
&&
354 (ret
== EXIT_OKAY
|| cmd_info
.cmd
!= ES_SIGN
); i
++) {
355 iret
= action(argv
[i
]);
363 free(cmd_info
.elfobj
);
373 (void) fprintf(stderr
, gettext(
375 "\telfsign sign [-v] [-e <elf_object>] -c <certificate_file>\n"
376 "\t\t[-F <format>] -k <private_key_file> [elf_object]..."
378 "\telfsign sign [-v] [-e <elf_object>] -c <certificate_file>\n"
379 "\t\t[-F <format>] -T <token_label> [-P <pin_file>] [elf_object]..."
381 "\telfsign verify [-v] [-c <certificate_file>] [-e <elf_object>]\n"
382 "\t\t[elf_object]..."
384 "\telfsign request -r <certificate_request_file> -k <private_key_file>"
386 "\telfsign request -r <certificate_request_file> -T <token_label>"
388 "\telfsign list -f field -c <certificate_file>"
390 "\telfsign list -f field -e <elf_object>"
396 getelfobj(char *elfpath
)
398 ELFsign_status_t estatus
;
399 ret_t ret
= EXIT_SIGN_FAILED
;
401 estatus
= elfsign_begin(elfpath
, cmd_info
.es_action
, &(cmd_info
.ess
));
403 case ELFSIGN_SUCCESS
:
406 case ELFSIGN_INVALID_ELFOBJ
:
408 "Unable to open %s as an ELF object."),
410 ret
= EXIT_CANT_OPEN_ELF_OBJECT
;
413 es_error(gettext("unexpected failure: %d"), estatus
);
414 if (cmd_info
.cmd
== ES_SIGN
) {
415 ret
= EXIT_SIGN_FAILED
;
416 } else if (cmd_info
.cmd
== ES_VERIFY
) {
417 ret
= EXIT_VERIFY_FAILED
;
427 ELFsign_status_t estatus
;
428 ret_t ret
= EXIT_SIGN_FAILED
;
430 if (cmd_info
.cert
== NULL
)
432 estatus
= elfsign_setcertpath(cmd_info
.ess
, cmd_info
.cert
);
434 case ELFSIGN_SUCCESS
:
437 case ELFSIGN_INVALID_CERTPATH
:
438 if (cmd_info
.cert
!= NULL
) {
439 es_error(gettext("Unable to open %s as a certificate."),
445 es_error(gettext("unusable certificate: %s"), cmd_info
.cert
);
446 if (cmd_info
.cmd
== ES_SIGN
) {
447 ret
= EXIT_SIGN_FAILED
;
448 } else if (cmd_info
.cmd
== ES_VERIFY
) {
449 ret
= EXIT_VERIFY_FAILED
;
457 * getpin - return pointer to token PIN in static storage
462 static char pinbuf
[PASS_MAX
+ 1];
466 if (cmd_info
.pinpath
== NULL
)
467 return (getpassphrase(
468 gettext("Enter PIN for PKCS#11 token: ")));
469 if ((pinfile
= fopen(cmd_info
.pinpath
, "r")) == NULL
) {
470 es_error(gettext("failed to open %s."),
475 pp
= fgets(pinbuf
, sizeof (pinbuf
), pinfile
);
476 (void) fclose(pinfile
);
478 es_error(gettext("failed to read PIN from %s."),
482 pp
= &pinbuf
[strlen(pinbuf
) - 1];
489 * Add the .SUNW_signature sections for the ELF signature
492 do_sign(char *object
)
495 ELFsign_status_t elfstat
;
496 struct filesignatures
*fssp
= NULL
;
498 uchar_t sig
[SIG_MAX_LENGTH
];
499 size_t sig_len
= SIG_MAX_LENGTH
;
500 uchar_t hash
[SIG_MAX_LENGTH
];
501 size_t hash_len
= SIG_MAX_LENGTH
;
502 ELFCert_t cert
= NULL
;
506 cryptodebug("do_sign");
507 if ((ret
= getelfobj(object
)) != EXIT_OKAY
)
510 if (cmd_info
.token_label
&&
511 !elfcertlib_settoken(cmd_info
.ess
, cmd_info
.token_label
)) {
512 es_error(gettext("Unable to access token: %s"),
513 cmd_info
.token_label
);
514 ret
= EXIT_SIGN_FAILED
;
518 if ((ret
= setcertpath()) != EXIT_OKAY
)
521 if (!elfcertlib_getcert(cmd_info
.ess
, cmd_info
.cert
, NULL
, &cert
,
522 cmd_info
.es_action
)) {
523 es_error(gettext("Unable to load certificate: %s"),
529 if (cmd_info
.privpath
!= NULL
) {
530 if (!elfcertlib_loadprivatekey(cmd_info
.ess
, cert
,
531 cmd_info
.privpath
)) {
532 es_error(gettext("Unable to load private key: %s"),
534 ret
= EXIT_BAD_PRIVATEKEY
;
538 char *pin
= getpin();
540 es_error(gettext("Unable to get PIN"));
541 ret
= EXIT_BAD_PRIVATEKEY
;
544 if (!elfcertlib_loadtokenkey(cmd_info
.ess
, cert
,
545 cmd_info
.token_label
, pin
)) {
546 es_error(gettext("Unable to access private key "
547 "in token %s"), cmd_info
.token_label
);
548 ret
= EXIT_BAD_PRIVATEKEY
;
554 * Get the DN from the certificate.
556 if ((dn
= elfcertlib_getdn(cert
)) == NULL
) {
557 es_error(gettext("Unable to find DN in certificate %s"),
559 ret
= EXIT_SIGN_FAILED
;
563 cryptodebug("DN = %s", dn
);
565 elfstat
= elfsign_signatures(cmd_info
.ess
, &fssp
, &fs_len
, ES_GET
);
566 if (elfstat
!= ELFSIGN_SUCCESS
) {
567 if (elfstat
!= ELFSIGN_NOTSIGNED
) {
568 es_error(gettext("Unable to retrieve existing "
569 "signature block in %s"), object
);
570 ret
= EXIT_SIGN_FAILED
;
575 * force creation and naming of signature section
576 * so the hash doesn't change
578 if (elfsign_signatures(cmd_info
.ess
, &fssp
, &fs_len
,
579 cmd_info
.es_action
) != ELFSIGN_SUCCESS
) {
580 es_error(gettext("Unable to insert "
581 "signature block into %s"), object
);
582 ret
= EXIT_SIGN_FAILED
;
587 bzero(hash
, sizeof (hash
));
588 if (elfsign_hash(cmd_info
.ess
, hash
, &hash_len
) != ELFSIGN_SUCCESS
) {
589 es_error(gettext("Unable to calculate hash of ELF object %s"),
591 ret
= EXIT_SIGN_FAILED
;
595 bzero(sig
, sizeof (sig
));
596 if (!elfcertlib_sign(cmd_info
.ess
, cert
,
597 hash
, hash_len
, sig
, &sig_len
)) {
598 es_error(gettext("Unable to sign %s using key from %s"),
599 object
, cmd_info
.privpath
?
600 cmd_info
.privpath
: cmd_info
.token_label
);
601 ret
= EXIT_SIGN_FAILED
;
606 const int sigstr_len
= sizeof (char) * sig_len
* 2 + 1;
607 char *sigstr
= malloc(sigstr_len
);
609 tohexstr(sig
, sig_len
, sigstr
, sigstr_len
);
610 cryptodebug("sig value is: %s", sigstr
);
614 fssp
= elfsign_insert_dso(cmd_info
.ess
, fssp
,
615 dn
, dn_len
, sig
, sig_len
, NULL
, 0);
617 es_error(gettext("Unable to prepare signature for %s"),
619 ret
= EXIT_SIGN_FAILED
;
622 if (elfsign_signatures(cmd_info
.ess
, &fssp
, &fs_len
,
623 cmd_info
.es_action
) != ELFSIGN_SUCCESS
) {
624 es_error(gettext("Unable to update %s: with signature"),
626 ret
= EXIT_SIGN_FAILED
;
629 if (cmd_info
.verbose
|| (cmd_info
.elfcnt
+ cmd_info
.extracnt
) > 1) {
630 (void) fprintf(stdout
,
631 gettext("elfsign: %s signed successfully.\n"),
634 if (cmd_info
.verbose
) {
635 struct ELFsign_sig_info
*esip
;
637 if (elfsign_sig_info(fssp
, &esip
)) {
638 sig_info_print(esip
);
639 elfsign_sig_info_free(esip
);
648 bzero(hash
, hash_len
);
651 elfcertlib_releasecert(cmd_info
.ess
, cert
);
652 if (cmd_info
.ess
!= NULL
)
653 elfsign_end(cmd_info
.ess
);
659 * Verify the signature of the object
660 * This subcommand is intended to be used by developers during their build
661 * processes. Therefore we can not assume that the certificate is in
662 * /etc/crypto/certs so we must use the path we got from the commandline.
665 do_verify(char *object
)
667 ELFsign_status_t res
;
668 struct ELFsign_sig_info
*esip
;
671 cryptodebug("do_verify");
672 if ((retval
= getelfobj(object
)) != EXIT_OKAY
)
675 if ((retval
= setcertpath()) != EXIT_OKAY
) {
676 elfsign_end(cmd_info
.ess
);
680 res
= elfsign_verify_signature(cmd_info
.ess
, &esip
);
682 case ELFSIGN_SUCCESS
:
683 (void) fprintf(stdout
,
684 gettext("elfsign: verification of %s passed.\n"),
686 if (cmd_info
.verbose
)
687 sig_info_print(esip
);
691 case ELFSIGN_INVALID_CERTPATH
:
692 es_error(gettext("verification of %s failed."),
694 if (cmd_info
.verbose
)
695 sig_info_print(esip
);
696 retval
= EXIT_VERIFY_FAILED
;
698 case ELFSIGN_NOTSIGNED
:
699 es_error(gettext("no signature found in %s."),
701 retval
= EXIT_VERIFY_FAILED_UNSIGNED
;
704 es_error(gettext("unexpected failure attempting verification "
706 retval
= EXIT_VERIFY_FAILED_UNSIGNED
;
711 elfsign_sig_info_free(esip
);
712 if (cmd_info
.ess
!= NULL
)
713 elfsign_end(cmd_info
.ess
);
717 #define SET_VALUE(f, s) \
719 if (kmfrv != KMF_OK) { \
721 (void) kmf_get_kmf_error_str(kmfrv, &e); \
722 cryptoerror(LOG_STDERR, \
723 gettext("Failed to %s: %s\n"), \
724 s, (e ? e : "unknown error")); \
732 KMF_RETURN kmfrv
= KMF_OK
;
733 KMF_HANDLE_T kmfhandle
= NULL
;
734 KMF_KEY_HANDLE pubk
, prik
;
735 KMF_X509_NAME csrSubject
;
737 KMF_ALGORITHM_INDEX sigAlg
= KMF_ALGID_MD5WithRSA
;
738 KMF_DATA signedCsr
= { 0, NULL
};
740 KMF_ATTRIBUTE attrlist
[16];
741 KMF_ENCODE_FORMAT format
;
742 KMF_KEYSTORE_TYPE kstype
;
749 if ((kmfrv
= kmf_initialize(&kmfhandle
, NULL
, NULL
)) != KMF_OK
) {
750 (void) kmf_get_kmf_error_str(kmfrv
, &err
);
751 cryptoerror(LOG_STDERR
,
752 gettext("Error initializing KMF: %s\n"),
753 (err
? err
: "unknown error"));
757 (void) memset(&csr
, 0, sizeof (csr
));
758 (void) memset(&csrSubject
, 0, sizeof (csrSubject
));
760 if (cmd_info
.privpath
!= NULL
) {
761 kstype
= KMF_KEYSTORE_OPENSSL
;
762 format
= KMF_FORMAT_ASN1
;
765 /* args checking verified (cmd_info.token_label != NULL) */
767 /* Get a PIN to store the private key in the token */
771 (void) kmf_finalize(kmfhandle
);
772 return (KMF_ERR_AUTH_FAILED
);
775 kstype
= KMF_KEYSTORE_PK11TOKEN
;
779 kmf_set_attr_at_index(attrlist
, numattr
++,
780 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
781 kmf_set_attr_at_index(attrlist
, numattr
++,
782 KMF_TOKEN_LABEL_ATTR
, cmd_info
.token_label
,
783 strlen(cmd_info
.token_label
));
784 kmf_set_attr_at_index(attrlist
, numattr
++,
785 KMF_READONLY_ATTR
, &readonly
, sizeof (readonly
));
786 kmfrv
= kmf_configure_keystore(kmfhandle
, numattr
, attrlist
);
787 if (kmfrv
!= KMF_OK
) {
792 /* Create the RSA keypair */
794 keylength
= ES_DEFAULT_KEYSIZE
;
795 (void) memset(&prik
, 0, sizeof (prik
));
796 (void) memset(&pubk
, 0, sizeof (pubk
));
799 kmf_set_attr_at_index(attrlist
, numattr
++,
800 KMF_KEYSTORE_TYPE_ATTR
, &kstype
, sizeof (kstype
));
801 kmf_set_attr_at_index(attrlist
, numattr
++,
802 KMF_KEYALG_ATTR
, &keytype
, sizeof (keytype
));
803 kmf_set_attr_at_index(attrlist
, numattr
++,
804 KMF_KEYLENGTH_ATTR
, &keylength
, sizeof (keylength
));
807 cred
.credlen
= strlen(pin
);
808 kmf_set_attr_at_index(attrlist
, numattr
++,
809 KMF_CREDENTIAL_ATTR
, &cred
, sizeof (KMF_CREDENTIAL
));
811 kmf_set_attr_at_index(attrlist
, numattr
++,
812 KMF_PRIVKEY_HANDLE_ATTR
, &prik
, sizeof (KMF_KEY_HANDLE
));
813 kmf_set_attr_at_index(attrlist
, numattr
++,
814 KMF_PUBKEY_HANDLE_ATTR
, &pubk
, sizeof (KMF_KEY_HANDLE
));
815 if (kstype
== KMF_KEYSTORE_OPENSSL
) {
816 kmf_set_attr_at_index(attrlist
, numattr
++,
817 KMF_KEY_FILENAME_ATTR
, cmd_info
.privpath
,
818 strlen(cmd_info
.privpath
));
819 kmf_set_attr_at_index(attrlist
, numattr
++,
820 KMF_ENCODE_FORMAT_ATTR
, &format
, sizeof (format
));
823 kmfrv
= kmf_create_keypair(kmfhandle
, numattr
, attrlist
);
824 if (kmfrv
!= KMF_OK
) {
825 (void) kmf_get_kmf_error_str(kmfrv
, &err
);
826 cryptoerror(LOG_STDERR
,
827 gettext("Create RSA keypair failed: %s"),
828 (err
? err
: "unknown error"));
833 kmfrv
= kmf_dn_parser(dn
, &csrSubject
);
834 if (kmfrv
!= KMF_OK
) {
835 (void) kmf_get_kmf_error_str(kmfrv
, &err
);
836 cryptoerror(LOG_STDERR
,
837 gettext("Error parsing subject name: %s\n"),
838 (err
? err
: "unknown error"));
843 SET_VALUE(kmf_set_csr_pubkey(kmfhandle
, &pubk
, &csr
), "keypair");
845 SET_VALUE(kmf_set_csr_version(&csr
, 2), "version number");
847 SET_VALUE(kmf_set_csr_subject(&csr
, &csrSubject
), "subject name");
849 SET_VALUE(kmf_set_csr_sig_alg(&csr
, sigAlg
), "SignatureAlgorithm");
851 if ((kmfrv
= kmf_sign_csr(kmfhandle
, &csr
, &prik
, &signedCsr
)) ==
853 kmfrv
= kmf_create_csr_file(&signedCsr
, KMF_FORMAT_PEM
,
858 (void) kmf_free_kmf_key(kmfhandle
, &prik
);
859 (void) kmf_free_data(&signedCsr
);
860 (void) kmf_free_signed_csr(&csr
);
861 (void) kmf_finalize(kmfhandle
);
867 #define CN_MAX_LENGTH 64 /* Verisign implementation limit */
869 * Generate a certificate request into the file named cmd_info.cert
873 do_cert_request(char *object
)
875 const char PartnerDNFMT
[] =
878 "OU=Solaris Cryptographic Framework, "
879 "OU=Partner Object Signing, "
880 "O=Sun Microsystems Inc";
881 const char SunCDNFMT
[] =
884 "OU=Solaris Cryptographic Framework, "
885 "OU=Corporate Object Signing, "
886 "O=Sun Microsystems Inc";
887 const char SunSDNFMT
[] =
890 "OU=Solaris Signed Execution, "
891 "OU=Corporate Object Signing, "
892 "O=Sun Microsystems Inc";
893 const char *dnfmt
= NULL
;
894 char cn
[CN_MAX_LENGTH
+ 1];
898 cryptodebug("do_cert_request");
901 * Get the DN prefix from the user
903 switch (cmd_info
.internal_req
) {
906 (void) fprintf(stdout
, gettext(
907 "Enter Sun Microsystems, Inc. Release name.\n"
908 "This will be the prefix of the Certificate DN: "));
912 (void) fprintf(stdout
, gettext(
913 "Enter Sun Microsystems, Inc. Release name.\n"
914 "This will be the prefix of the Certificate DN: "));
917 dnfmt
= PartnerDNFMT
;
918 (void) fprintf(stdout
, gettext(
919 "Enter Company Name / Stock Symbol"
920 " or some other globally unique identifier.\n"
921 "This will be the prefix of the Certificate DN: "));
924 if ((fgets(cn
, sizeof (cn
), stdin
) == NULL
) || (cn
[0] == '\n')) {
925 es_error(gettext("you must specify a Certificate DN prefix"));
926 return (EXIT_INVALID_ARG
);
929 if (cn
[strlen(cn
) - 1] == '\n') {
930 cn
[strlen(cn
) - 1] = '\0'; /* chop trailing \n */
932 es_error(gettext("You must specify a Certificate DN prefix "
933 "of no more than %d characters"), CN_MAX_LENGTH
);
934 return (EXIT_INVALID_ARG
);
937 /* Update DN string */
938 dn_len
= strlen(cn
) + strlen(dnfmt
);
939 dn
= malloc(dn_len
+ 1);
940 (void) snprintf(dn
, dn_len
, dnfmt
, cn
);
942 cryptodebug("Generating Certificate request for DN: %s", dn
);
943 kmfret
= create_csr(dn
);
945 if (kmfret
== KMF_OK
)
948 return (EXIT_CSR_FAILED
);
956 (void) fprintf(stdout
, "%s\n", s
);
961 do_list(char *object
)
965 if (cmd_info
.elfcnt
> 0) {
966 ELFsign_status_t elfstat
;
967 struct filesignatures
*fssp
= NULL
;
969 struct ELFsign_sig_info
*esip
;
971 if ((retval
= getelfobj(cmd_info
.elfobj
[0])) != EXIT_OKAY
)
973 elfstat
= elfsign_signatures(cmd_info
.ess
,
974 &fssp
, &fs_len
, ES_GET
);
975 if (elfstat
== ELFSIGN_SUCCESS
) {
977 if (elfsign_sig_info(fssp
, &esip
)) {
978 switch (cmd_info
.field
) {
980 str_print(esip
->esi_format
);
983 str_print(esip
->esi_signer
);
986 if (esip
->esi_time
== 0)
987 retval
= EXIT_INVALID_ARG
;
993 retval
= EXIT_INVALID_ARG
;
995 elfsign_sig_info_free(esip
);
999 retval
= EXIT_VERIFY_FAILED_UNSIGNED
;
1000 elfsign_end(cmd_info
.ess
);
1004 * Initialize the ESS record here even though we are not
1005 * actually opening any ELF files.
1007 if (elfsign_begin(NULL
, ES_GET
, &(cmd_info
.ess
)) !=
1009 return (EXIT_MEMORY_ERROR
);
1011 if (elfcertlib_getcert(cmd_info
.ess
, cmd_info
.cert
, NULL
,
1012 &cert
, cmd_info
.es_action
)) {
1014 switch (cmd_info
.field
) {
1016 str_print(elfcertlib_getdn(cert
));
1019 str_print(elfcertlib_getissuer(cert
));
1022 retval
= EXIT_INVALID_ARG
;
1024 elfcertlib_releasecert(cmd_info
.ess
, cert
);
1026 retval
= EXIT_BAD_CERT
;
1027 elfsign_end(cmd_info
.ess
);
1034 es_error(const char *fmt
, ...)
1036 char msgbuf
[BUFSIZ
];
1039 va_start(args
, fmt
);
1040 (void) vsnprintf(msgbuf
, sizeof (msgbuf
), fmt
, args
);
1042 (void) fflush(stdout
);
1043 cryptoerror(LOG_STDERR
, "%s", msgbuf
);
1044 (void) fflush(stderr
);
1050 static char buf
[80];
1054 if (strftime(buf
, sizeof (buf
), NULL
, localtime(&t
)) == 0)
1060 sig_info_print(struct ELFsign_sig_info
*esip
)
1064 (void) fprintf(stdout
, gettext("format: %s.\n"), esip
->esi_format
);
1065 (void) fprintf(stdout
, gettext("signer: %s.\n"), esip
->esi_signer
);
1066 if (esip
->esi_time
== 0)
1068 (void) fprintf(stdout
, gettext("signed on: %s.\n"),
1069 time_str(esip
->esi_time
));