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 "Copy PKCS#11 token object with a new label.\n\n"
32
33 /* prototypes */
34 void print_usage(char *);
35 void print_version_info(char *progname);
36 int main( int argc, char **argv);
37
38
print_usage(char * progname)39 void print_usage(char *progname)
40 {
41 fprintf( stderr,
42 "USAGE: %s OPTIONS SOURCE DESTINATION\n"
43 "\n"
44 COMMAND_SUMMARY
45 "OPTIONS:\n"
46 "* -l <pkcs#11 library path> : path to PKCS#11 library\n"
47 " -m <NSS config dir> ( e.g. '.' or 'sql:.' ) : NSS db directory \n"
48 " -s <slot number>\n"
49 " -t <token label> : if present, -s option is ignored\n"
50 " -p <token PIN> | :::exec:<command> | :::nologin\n"
51 " -S : login with SO privilege\n"
52 " -y : force positive answer (non-interactive)\n"
53 " -v : verbose\n"
54 " -h : print usage information\n"
55 " -V : print version information\n"
56 "|\n"
57 "+-> arguments marked with an asterix(*) are mandatory\n"
58 "| (except if environment variable sets the value)\n"
59 "+-> arguments marked with a plus sign(+) can be repeated\n"
60 "\n"
61 "ARGUMENTS:\n"
62 " SOURCE : source object label to move\n"
63 " can be prefixed with cert/, prvk/, pubk/ or seck/)\n"
64 " if no prefix, objects from all classes sharing the\n"
65 " same label are moved\n"
66 " DESTINATION : target label\n"
67 "\n"
68 " ENVIRONMENT VARIABLES:\n"
69 " PKCS11LIB : path to PKCS#11 library,\n"
70 " overriden by option -l\n"
71 " PKCS11NSSDIR : NSS configuration directory directive,\n"
72 " overriden by option -m\n"
73 " PKCS11SLOT : token slot (integer)\n"
74 " overriden by PKCS11TOKENLABEL,\n"
75 " options -t or -s\n"
76 " PKCS11TOKENLABEL : token label\n"
77 " overriden by options -t or -s\n"
78 " PKCS11PASSWORD : password\n"
79 " overriden by option -p\n"
80 "\n"
81 , progname );
82
83 exit( RC_ERROR_USAGE );
84 }
85
main(int argc,char ** argv)86 int main( int argc, char ** argv )
87 {
88 extern char *optarg;
89 extern int optind, optopt;
90 int argnum = 0;
91 int errflag = 0;
92 char * library = NULL;
93 char * nsscfgdir = NULL;
94 char * password = NULL;
95 char * slotenv = NULL;
96 int slot = -1;
97 int interactive = 1;
98 int ask_confirm = 1;
99 char * tokenlabel = NULL;
100 int so=0;
101 int verbose=0;
102
103 pkcs11Context * p11Context = NULL;
104 func_rc retcode = rc_error_usage;
105
106 library = getenv("PKCS11LIB");
107 nsscfgdir = getenv("PKCS11NSSDIR");
108 tokenlabel = getenv("PKCS11TOKENLABEL");
109 if(tokenlabel==NULL) {
110 slotenv = getenv("PKCS11SLOT");
111 if (slotenv!=NULL) {
112 slot=atoi(slotenv);
113 }
114 }
115 password = getenv("PKCS11PASSWORD");
116
117 /* if a slot or a token is given, interactive is null */
118 if(slotenv!=NULL || tokenlabel!=NULL) {
119 interactive=0;
120 }
121
122 /* get the command-line arguments */
123 while ( ( argnum = getopt( argc, argv, "l:m:p:s:t:yvShV)" ) ) != -1 )
124 {
125 switch ( argnum )
126 {
127 case 'l' :
128 library = optarg;
129 break;
130
131 case 'm':
132 nsscfgdir = optarg;
133 break;
134
135 case 'p' :
136 password = optarg;
137 break;
138
139 case 's':
140 slot = atoi(optarg);
141 tokenlabel = NULL;
142 interactive = 0;
143 break;
144
145 case 't':
146 tokenlabel = optarg;
147 slot = -1;
148 interactive = 0;
149 break;
150
151 case 'y':
152 ask_confirm = 0;
153 break;
154
155 case 'v':
156 verbose = 1;
157 break;
158
159 case 'S':
160 so=1;
161 break;
162
163 case 'h':
164 print_usage(argv[0]);
165 break;
166
167 case 'V':
168 print_version_info(argv[0]);
169 break;
170
171 default:
172 errflag++;
173 break;
174 }
175 }
176
177 if ( errflag ) {
178 fprintf(stderr, "Try `%s -h' for more information.\n", argv[0]);
179 goto err;
180 }
181
182
183 if ( library == NULL || optind!=argc-2 ) {
184 fprintf( stderr, "At least one required option or argument is wrong or missing.\n"
185 "Try `%s -h' for more information.\n", argv[0]);
186 goto err;
187 }
188
189 if((p11Context = pkcs11_newContext( library, nsscfgdir ))==NULL) {
190 goto err;
191 }
192
193 /* validate the given provider library exists and can be opened */
194 if (( retcode = pkcs11_initialize( p11Context ) ) != CKR_OK ) {
195 goto err;
196 }
197
198 retcode = pkcs11_open_session( p11Context, slot, tokenlabel, password, so, interactive);
199
200 if ( retcode == rc_ok )
201 {
202 pkcs11_cp_objects(p11Context, argv[optind], argv[optind+1], ask_confirm, verbose);
203
204 pkcs11_close_session( p11Context );
205 }
206 pkcs11_finalize( p11Context );
207
208 /* free allocated memory */
209 err:
210 pkcs11_freeContext(p11Context);
211
212 return retcode;
213 }
214