1 /* -*- mode: c; c-file-style:"stroustrup"; -*- */
2 
3 /*
4  * Copyright (c) 2018 Mastercard
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <config.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include "pkcs11lib.h"
25 
26 #ifdef _WIN32
27 #include <openssl/applink.c>
28 #endif
29 
30 #define COMMAND_SUMMARY \
31     "Display in human-readable format non-sensitive content of PKCS#11 token object(s).\n\n"
32 
33 
34 /* prototypes */
35 void print_version_info(char *progname);
36 void print_usage(char *);
37 int main( int argc, char **argv);
38 
39 
print_usage(char * progname)40 void print_usage(char *progname)
41 {
42     fprintf( stderr,
43 	     "USAGE: %s OPTIONS FILTERS\n"
44 	     "\n"
45 	     COMMAND_SUMMARY
46 	     "OPTIONS:\n"
47 	     "* -l <pkcs#11 library path> : path to PKCS#11 library\n"
48 	     "  -m <NSS config dir> ( e.g. '.' or 'sql:.' ) : NSS db directory \n"
49 	     "  -s <slot number>\n"
50 	     "  -t <token label> : if present, -s option is ignored\n"
51 	     "  -p <token PIN> | :::exec:<command> | :::nologin\n"
52 	     "  -S : login with SO privilege\n"
53 	     "  -h : print usage information\n"
54 	     "  -V : print version information\n"
55 	     "|\n"
56 	     "+-> arguments marked with an asterix(*) are mandatory\n"
57              "|   (except if environment variable sets the value)\n"
58 	     "+-> arguments marked with a plus sign(+) can be repeated\n"
59 	     "\n"
60 	     "FILTERS:\n"
61 	     " FILTER [FILTER ...]: object filter to match, of the form:\n"
62 	     "                      - TYPE\n"
63              "                      - [TYPE/[ATTRIBUTE/]]VALUE\n"
64 	     "\n"
65 	     "                      TYPE can be 'cert', 'pubk', 'prvk', 'seck', 'data'\n"
66 	     "                      when omitted, all objects are listed\n"
67 	     "\n"
68 	     "                      ATTRIBUTE is either:\n"
69              "                      - 'id', 'label' or 'sn'\n"
70 	     "                      - an actual PKCS#11 attribute name (e.g. CKA_ENCRYPT)\n"
71 	     "                      when omitted, default is 'label'\n"
72 	     "\n"
73 	     "                      VALUE is either:\n"
74 	     "                      - ASCII string\n"
75 	     "                      - {hexadecimal values} between curly braces\n"
76 	     "\n"
77              " ENVIRONMENT VARIABLES:\n"
78 	     "    PKCS11LIB         : path to PKCS#11 library,\n"
79              "                        overriden by option -l\n"
80 	     "    PKCS11NSSDIR      : NSS configuration directory directive,\n"
81              "                        overriden by option -m\n"
82 	     "    PKCS11SLOT        : token slot (integer)\n"
83 	     "                        overriden by PKCS11TOKENLABEL,\n"
84 	     "                        options -t or -s\n"
85 	     "    PKCS11TOKENLABEL  : token label\n"
86 	     "                        overriden by options -t or -s\n"
87 	     "    PKCS11PASSWORD    : password\n"
88              "                        overriden by option -p\n"
89 	     "\n"
90 	     , pkcs11_ll_basename(progname) );
91 
92     exit( RC_ERROR_USAGE );
93 }
94 
main(int argc,char ** argv)95 int main( int argc, char ** argv )
96 {
97     extern char *optarg;
98     extern int optind, optopt;
99     int argnum = 0;
100     int errflag = 0;
101     char * library = NULL;
102     char * nsscfgdir = NULL;
103     char * password = NULL;
104     char * slotenv = NULL;
105     int slot = -1;
106     int interactive = 1;
107     char * tokenlabel = NULL;
108     int so=0;
109 
110     pkcs11Context * p11Context = NULL;
111     func_rc retcode = rc_error_usage;
112 
113     library = getenv("PKCS11LIB");
114     nsscfgdir = getenv("PKCS11NSSDIR");
115     tokenlabel = getenv("PKCS11TOKENLABEL");
116     if(tokenlabel==NULL) {
117 	slotenv = getenv("PKCS11SLOT");
118 	if (slotenv!=NULL) {
119 	    slot=atoi(slotenv);
120 	}
121     }
122     password = getenv("PKCS11PASSWORD");
123 
124     /* get the command-line arguments */
125     while ( ( argnum = getopt( argc, argv, "l:m:p:s:t:ShV" ) ) != -1 )
126     {
127 	switch ( argnum )
128 	{
129 	case 'l' :
130 	    library =  optarg;
131 	    break;
132 
133 	case 'm':
134 	    nsscfgdir = optarg;
135 	    break;
136 
137 	case 'p' :
138 	    password = optarg;
139 	    break;
140 
141 	case 's':
142 	    slot = atoi(optarg);
143 	    interactive = 0;
144 	    tokenlabel = NULL;
145 	    break;
146 
147 	case 't':
148 	    tokenlabel = optarg;
149 	    interactive = 0;
150 	    slot = -1;
151 	    break;
152 
153 	case 'S':
154 	    so=1;
155 	  break;
156 
157 	case 'h':
158 	    print_usage(argv[0]);
159 	    break;
160 
161 	case 'V':
162 	    print_version_info(argv[0]);
163 	    break;
164 
165 	default:
166 	    errflag++;
167 	    break;
168 	}
169     }
170 
171     if ( errflag ) {
172 	fprintf(stderr, "Try `%s -h' for more information.\n", argv[0]);
173 	goto err;
174     }
175 
176 
177     if ( library == NULL || optind==argc ) {
178 	fprintf( stderr, "At least one required option or argument is wrong or missing.\n"
179 		 "Try `%s -h' for more information.\n", argv[0]);
180 	goto err;
181     }
182 
183     if((p11Context = pkcs11_newContext( library, nsscfgdir ))==NULL) {
184       goto err;
185     }
186 
187     /* validate the given provider library exists and can be opened */
188     if (( retcode = pkcs11_initialize( p11Context ) ) != CKR_OK ) {
189       goto err;
190     }
191 
192 
193     retcode = pkcs11_open_session( p11Context, slot, tokenlabel, password, so, interactive);
194 
195     if ( retcode == rc_ok )
196     {
197 	while(optind<argc) {
198 	    pkcs11_more_object_with_label(p11Context, argv[optind++]);
199 	}
200 
201 	pkcs11_close_session( p11Context );
202     }
203 
204     pkcs11_finalize( p11Context );
205 
206     /* free allocated memory */
207  err:
208     pkcs11_freeContext(p11Context);
209 
210     return retcode;
211 }
212