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
20 #include <config.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <ctype.h>
26 #include "pkcs11lib.h"
27
28
29 /* high-level search functions */
30
pkcs11_cp_objects(pkcs11Context * p11Context,char * src,char * dest,int interactive,int verbose)31 int pkcs11_cp_objects(pkcs11Context *p11Context, char *src, char *dest, int interactive, int verbose)
32 {
33
34 int rv=0;
35 pkcs11Search *search=NULL;
36 pkcs11IdTemplate *idtmpl=NULL;
37 char *destlabel;
38 typedef enum { all, cert, pubk, prvk, seck } objtype;
39
40 objtype whatsrc = all, whatdest = all;
41
42
43
44 /* check source */
45
46 if(strncasecmp("prvk/", src, 5) ==0 ) { /* private key case */
47 whatsrc = prvk;
48 } else if (strncasecmp("pubk/", src, 5) ==0 ) { /* public key case */
49 whatsrc = pubk;
50 } else if (strncasecmp("seck/", src, 5) ==0 ) { /* secret key case */
51 whatsrc = seck;
52 } else if (strncasecmp("cert/", src, 5) ==0 ) { /* cert case */
53 whatsrc = cert;
54 } else { /* generic case */
55 whatsrc = all;
56 }
57
58
59 /* check dest */
60
61 if(strncasecmp("prvk/", dest, 5) ==0 ) { /* private key case */
62 whatdest = prvk;
63 destlabel = &dest[5];
64 } else if (strncasecmp("pubk/", dest, 5) ==0 ) { /* public key case */
65 whatdest = pubk;
66 destlabel = &dest[5];
67 } else if (strncasecmp("seck/", dest, 5) ==0 ) { /* secret key case */
68 whatdest = seck;
69 destlabel = &dest[5];
70 } else if (strncasecmp("cert/", dest, 5) ==0 ) { /* cert case */
71 whatdest = cert;
72 destlabel = &dest[5];
73 } else { /* generic case */
74 whatdest = all;
75 destlabel = dest;
76 }
77
78 /* compare src and dest */
79
80 if (whatsrc != whatdest) {
81 fprintf(stderr, "source and destination must be of the same kind. Use same prefix for both.\n");
82 rv = RC_ERROR_USAGE;
83 goto error;
84 }
85
86
87 switch(whatsrc) {
88
89 case all:
90 if(pkcs11_label_exists( p11Context, dest)) {
91 fprintf(stderr, "Error: at least one object already exists for destination label '%s'.\n", dest);
92 rv = RC_ERROR_OBJECT_EXISTS;
93 goto error;
94 }
95 break;
96
97 case prvk:
98 if(pkcs11_privatekey_exists( p11Context, dest)) {
99 fprintf(stderr,"Error: a private key already exists for destination label '%s'.\n", dest);
100 rv = RC_ERROR_OBJECT_EXISTS;
101 goto error;
102 }
103 break;
104
105 case pubk:
106 if(pkcs11_publickey_exists( p11Context, dest)) {
107 fprintf(stderr,"Error: a public key already exists for destination label '%s'.\n", dest);
108 rv = RC_ERROR_OBJECT_EXISTS;
109 goto error;
110 }
111 break;
112
113 case seck:
114 if(pkcs11_secretkey_exists( p11Context, dest)) {
115 fprintf(stderr,"Error: a secret key already exists for destination label '%s'.\n", dest);
116 rv = RC_ERROR_OBJECT_EXISTS;
117 goto error;
118 }
119 break;
120
121 case cert:
122 if(pkcs11_certificate_exists( p11Context, dest)) {
123 fprintf(stderr,"Error: a certificate already exists for destination label '%s'.\n", dest);
124 rv = RC_ERROR_OBJECT_EXISTS;
125 goto error;
126 }
127 break;
128
129 }
130
131
132 idtmpl = pkcs11_make_idtemplate(src);
133
134 if(idtmpl && pkcs11_sizeof_idtemplate(idtmpl)>0) {
135
136 search = pkcs11_new_search_from_idtemplate( p11Context, idtmpl );
137
138 if(search) {
139
140 CK_OBJECT_HANDLE hndl=0;
141 int ok_to_copy=1;
142 char choice;
143
144 while( (hndl = pkcs11_fetch_next(search))!=0 ) {
145
146 if(interactive) {
147 pkcs11AttrList *attrs;
148 char *prefixptr;
149 ok_to_copy=0;
150
151 attrs = pkcs11_new_attrlist(p11Context,
152 _ATTR(CKA_CLASS),
153 _ATTR(CKA_LABEL),
154 _ATTR_END );
155
156 if( pkcs11_read_attr_from_handle (attrs, hndl) == true) {
157
158 CK_ATTRIBUTE_PTR oclass = pkcs11_get_attr_in_attrlist(attrs, CKA_CLASS);
159 CK_ATTRIBUTE_PTR olabel = pkcs11_get_attr_in_attrlist(attrs, CKA_LABEL);
160
161 if(oclass) {
162 switch(*(CK_OBJECT_CLASS *)(oclass->pValue)) {
163 case CKO_PRIVATE_KEY:
164 prefixptr = "prvk/";
165 break;
166
167 case CKO_PUBLIC_KEY:
168 prefixptr = "pubk/";
169 break;
170
171 case CKO_SECRET_KEY:
172 prefixptr = "seck/";
173 break;
174
175 case CKO_CERTIFICATE:
176 prefixptr = "cert/";
177 break;
178
179 default:
180 prefixptr = "";
181 break;
182 }
183
184 fflush(stdin);
185
186 fprintf(stderr,
187 "copy %s%.*s to %s%.*s ? (y/N)",
188 prefixptr,
189 (int)(olabel->ulValueLen),
190 (char *)(olabel->pValue),
191
192 prefixptr,
193 (int)strlen(destlabel),
194 destlabel );
195
196 fflush(stderr);
197
198 choice = getchar();
199 /* eat rest of the line + carriage return */
200 { int c; while( (c = getchar()) != EOF && c!= '\n'); }
201
202 if ( tolower(choice) == 'y') {
203 ok_to_copy = 1;
204 }
205 }
206 }
207 pkcs11_delete_attrlist(attrs);
208 }
209
210
211 if(ok_to_copy) {
212 CK_RV rc;
213 CK_OBJECT_HANDLE tmp;
214
215 CK_ATTRIBUTE destattr[1] = {
216 { CKA_LABEL, NULL, 0L },
217 };
218
219
220 destattr[0].pValue = destlabel;
221 destattr[0].ulValueLen = strlen(destlabel);
222
223 rc = p11Context->FunctionList.C_CopyObject( p11Context->Session, hndl, destattr, (sizeof destattr)/sizeof(CK_ATTRIBUTE), &tmp);
224
225 if(rc != CKR_OK) {
226 pkcs11_error( rc, "C_CopyObject" );
227 rv = RC_ERROR_PKCS11_API;
228 goto error;
229 }
230
231 /* destattr[0].pValue = &ck_true; */
232
233 /* rc = p11Context->FunctionList.C_CopyObject( p11Context->Session, tmp, destattr, 1, &target); */
234
235 /* if(rc != CKR_OK) { */
236 /* pkcs11_error( rc, "C_CopyObject" ); */
237 /* rv = RC_ERROR_PKCS11_API; */
238 /* /\* goto error; *\/ */
239 /* } */
240 }
241 }
242 }
243 }
244 error:
245 if(search) { pkcs11_delete_search(search); }
246 if(idtmpl) { pkcs11_delete_idtemplate(idtmpl); }
247
248 return rv;
249 }
250
251 /* EOF */
252