6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "@(#)mechstr.c 1.6 08/01/07 SMI"
27
28 /*
29 * Convert Algorithm names as strings to PKCS#11 Mech numbers and vice versa.
30 */
31
32 #include <string.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <security/cryptoki.h>
36 #include <security/pkcs11t.h>
37
38 #include <cryptoutil.h>
39
40 /*
41 * This table is a one-to-one mapping between mechanism names and numbers.
42 * As such, it should not contain deprecated mechanism names (aliases).
43 */
44 static const struct {
45 const char *str;
46 CK_MECHANISM_TYPE mech;
47 } mapping[] = {
48 { "CKM_RSA_PKCS_KEY_PAIR_GEN", CKM_RSA_PKCS_KEY_PAIR_GEN },
49 { "CKM_RSA_PKCS", CKM_RSA_PKCS },
50 { "CKM_RSA_9796", CKM_RSA_9796 },
51 { "CKM_RSA_X_509", CKM_RSA_X_509 },
52 { "CKM_MD2_RSA_PKCS", CKM_MD2_RSA_PKCS },
53 { "CKM_MD5_RSA_PKCS", CKM_MD5_RSA_PKCS },
54 { "CKM_SHA1_RSA_PKCS", CKM_SHA1_RSA_PKCS },
55 { "CKM_RIPEMD128_RSA_PKCS", CKM_RIPEMD128_RSA_PKCS },
56 { "CKM_RIPEMD160_RSA_PKCS", CKM_RIPEMD160_RSA_PKCS },
57 { "CKM_RSA_PKCS_OAEP", CKM_RSA_PKCS_OAEP },
58 { "CKM_RSA_X9_31_KEY_PAIR_GEN", CKM_RSA_X9_31_KEY_PAIR_GEN },
59 { "CKM_RSA_X9_31", CKM_RSA_X9_31 },
60 { "CKM_SHA1_RSA_X9_31", CKM_SHA1_RSA_X9_31 },
61 { "CKM_RSA_PKCS_PSS", CKM_RSA_PKCS_PSS },
62 { "CKM_SHA1_RSA_PKCS_PSS", CKM_SHA1_RSA_PKCS_PSS },
63 { "CKM_DSA_KEY_PAIR_GEN", CKM_DSA_KEY_PAIR_GEN },
64 { "CKM_DSA", CKM_DSA },
65 { "CKM_DSA_SHA1", CKM_DSA_SHA1 },
66 { "CKM_DH_PKCS_KEY_PAIR_GEN", CKM_DH_PKCS_KEY_PAIR_GEN },
67 { "CKM_DH_PKCS_DERIVE", CKM_DH_PKCS_DERIVE },
276 { "CKM_AES_KEY_GEN", CKM_AES_KEY_GEN },
277 { "CKM_AES_ECB", CKM_AES_ECB },
278 { "CKM_AES_CBC", CKM_AES_CBC },
279 { "CKM_AES_MAC", CKM_AES_MAC },
280 { "CKM_AES_MAC_GENERAL", CKM_AES_MAC_GENERAL },
281 { "CKM_AES_CBC_PAD", CKM_AES_CBC_PAD },
282 { "CKM_AES_CTR", CKM_AES_CTR },
283 { "CKM_BLOWFISH_KEY_GEN", CKM_BLOWFISH_KEY_GEN },
284 { "CKM_BLOWFISH_CBC", CKM_BLOWFISH_CBC },
285 { "CKM_TWOFISH_KEY_GEN", CKM_TWOFISH_KEY_GEN },
286 { "CKM_TWOFISH_CBC", CKM_TWOFISH_CBC },
287 { "CKM_DES_ECB_ENCRYPT_DATA", CKM_DES_ECB_ENCRYPT_DATA },
288 { "CKM_DES_CBC_ENCRYPT_DATA", CKM_DES_CBC_ENCRYPT_DATA },
289 { "CKM_DES3_ECB_ENCRYPT_DATA", CKM_DES3_ECB_ENCRYPT_DATA },
290 { "CKM_DES3_CBC_ENCRYPT_DATA", CKM_DES3_CBC_ENCRYPT_DATA },
291 { "CKM_AES_ECB_ENCRYPT_DATA", CKM_AES_ECB_ENCRYPT_DATA },
292 { "CKM_AES_CBC_ENCRYPT_DATA", CKM_AES_CBC_ENCRYPT_DATA },
293 { "CKM_DSA_PARAMETER_GEN", CKM_DSA_PARAMETER_GEN },
294 { "CKM_DH_PKCS_PARAMETER_GEN", CKM_DH_PKCS_PARAMETER_GEN },
295 { "CKM_X9_42_DH_PARAMETER_GEN", CKM_X9_42_DH_PARAMETER_GEN },
296 { "CKM_VENDOR_DEFINED", CKM_VENDOR_DEFINED },
297 { NULL, 0 }
298 };
299
300 /*
301 * pkcs11_mech2str - convert PKCS#11 mech to a string
302 *
303 * Anything below CKM_VENDOR_DEFINED that wasn't in the mapping table
304 * at build time causes NULL to be returned. Anything above it also
305 * returns NULL since we have no way to know what its real name is.
306 */
307 char
308 *pkcs11_mech2str(CK_MECHANISM_TYPE mech)
309 {
310 int i;
311 char buf[11]; /* Num chars for representing ulong in ASCII */
312
313 if (mech > CKM_VENDOR_DEFINED) {
314 (void) snprintf(buf, sizeof (buf), "%#lx", mech);
315 return (strdup(buf));
316 }
317
318 for (i = 0; mapping[i].str; i++) {
319 if (mapping[i].mech == mech)
320 return (strdup(mapping[i].str));
321 }
322
323 return (NULL);
324 }
325
326 /*
327 * pkcs11_str2mech - convert a string into a PKCS#11 mech number.
328 *
329 * Since there isn't reserved value for an invalid mech we return
330 * CKR_MECHANISM_INVALID for anything we don't recognise.
331 * The value in mech isn't meaningful in these cases.
332 */
333 CK_RV
334 pkcs11_str2mech(char *mech_str, CK_MECHANISM_TYPE_PTR mech)
335 {
336 int i;
337 char *tmech_str;
338
339 if (mech_str == NULL)
340 return (CKR_MECHANISM_INVALID);
341
342 if (strncasecmp(mech_str, "0x8", 3) == 0) {
343 cryptodebug("pkcs11_str2mech: hex string passed in: %s",
344 mech_str);
345 *mech = strtoll(mech_str, NULL, 16);
346 return (CKR_OK);
347 }
348
349 if (strncasecmp(mech_str, "CKM_", 4) != 0) {
350 size_t tmech_strlen = strlen(mech_str) + 4 + 1;
351 cryptodebug("pkcs11_str2mech: no CKM_ prefix: %s", mech_str);
352 tmech_str = malloc(tmech_strlen * sizeof (char));
353 (void) snprintf(tmech_str, tmech_strlen, "CKM_%s", mech_str);
354 cryptodebug("pkcs11_str2mech: with prefix: %s", tmech_str);
355 } else {
356 tmech_str = mech_str;
357 }
358
359 for (i = 0; mapping[i].str; i++) {
360 if (strcasecmp(mapping[i].str, tmech_str) == 0) {
361 *mech = mapping[i].mech;
362 if (tmech_str != mech_str)
363 free(tmech_str);
364 return (CKR_OK);
365 }
366 }
367 if (tmech_str != mech_str)
368 free(tmech_str);
369
370 return (CKR_MECHANISM_INVALID);
371 }
|
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "@(#)mechstr.c 1.7 08/06/30 SMI"
27
28 /*
29 * Convert Algorithm names as strings to PKCS#11 Mech numbers and vice versa.
30 */
31
32 #include <limits.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <security/cryptoki.h>
37 #include <security/pkcs11t.h>
38
39 #include <cryptoutil.h>
40
41 /*
42 * This table is a one-to-one mapping between mechanism names and numbers.
43 * As such, it should not contain deprecated mechanism names (aliases).
44 */
45 typedef struct {
46 const char *str;
47 CK_MECHANISM_TYPE mech;
48 } pkcs11_mapping_t;
49
50 /*
51 * Note: elements in this table MUST be in numeric order,
52 * since bsearch(3C) is used to search this table.
53 */
54 static const pkcs11_mapping_t mapping[] = {
55 { "CKM_RSA_PKCS_KEY_PAIR_GEN", CKM_RSA_PKCS_KEY_PAIR_GEN },
56 { "CKM_RSA_PKCS", CKM_RSA_PKCS },
57 { "CKM_RSA_9796", CKM_RSA_9796 },
58 { "CKM_RSA_X_509", CKM_RSA_X_509 },
59 { "CKM_MD2_RSA_PKCS", CKM_MD2_RSA_PKCS },
60 { "CKM_MD5_RSA_PKCS", CKM_MD5_RSA_PKCS },
61 { "CKM_SHA1_RSA_PKCS", CKM_SHA1_RSA_PKCS },
62 { "CKM_RIPEMD128_RSA_PKCS", CKM_RIPEMD128_RSA_PKCS },
63 { "CKM_RIPEMD160_RSA_PKCS", CKM_RIPEMD160_RSA_PKCS },
64 { "CKM_RSA_PKCS_OAEP", CKM_RSA_PKCS_OAEP },
65 { "CKM_RSA_X9_31_KEY_PAIR_GEN", CKM_RSA_X9_31_KEY_PAIR_GEN },
66 { "CKM_RSA_X9_31", CKM_RSA_X9_31 },
67 { "CKM_SHA1_RSA_X9_31", CKM_SHA1_RSA_X9_31 },
68 { "CKM_RSA_PKCS_PSS", CKM_RSA_PKCS_PSS },
69 { "CKM_SHA1_RSA_PKCS_PSS", CKM_SHA1_RSA_PKCS_PSS },
70 { "CKM_DSA_KEY_PAIR_GEN", CKM_DSA_KEY_PAIR_GEN },
71 { "CKM_DSA", CKM_DSA },
72 { "CKM_DSA_SHA1", CKM_DSA_SHA1 },
73 { "CKM_DH_PKCS_KEY_PAIR_GEN", CKM_DH_PKCS_KEY_PAIR_GEN },
74 { "CKM_DH_PKCS_DERIVE", CKM_DH_PKCS_DERIVE },
283 { "CKM_AES_KEY_GEN", CKM_AES_KEY_GEN },
284 { "CKM_AES_ECB", CKM_AES_ECB },
285 { "CKM_AES_CBC", CKM_AES_CBC },
286 { "CKM_AES_MAC", CKM_AES_MAC },
287 { "CKM_AES_MAC_GENERAL", CKM_AES_MAC_GENERAL },
288 { "CKM_AES_CBC_PAD", CKM_AES_CBC_PAD },
289 { "CKM_AES_CTR", CKM_AES_CTR },
290 { "CKM_BLOWFISH_KEY_GEN", CKM_BLOWFISH_KEY_GEN },
291 { "CKM_BLOWFISH_CBC", CKM_BLOWFISH_CBC },
292 { "CKM_TWOFISH_KEY_GEN", CKM_TWOFISH_KEY_GEN },
293 { "CKM_TWOFISH_CBC", CKM_TWOFISH_CBC },
294 { "CKM_DES_ECB_ENCRYPT_DATA", CKM_DES_ECB_ENCRYPT_DATA },
295 { "CKM_DES_CBC_ENCRYPT_DATA", CKM_DES_CBC_ENCRYPT_DATA },
296 { "CKM_DES3_ECB_ENCRYPT_DATA", CKM_DES3_ECB_ENCRYPT_DATA },
297 { "CKM_DES3_CBC_ENCRYPT_DATA", CKM_DES3_CBC_ENCRYPT_DATA },
298 { "CKM_AES_ECB_ENCRYPT_DATA", CKM_AES_ECB_ENCRYPT_DATA },
299 { "CKM_AES_CBC_ENCRYPT_DATA", CKM_AES_CBC_ENCRYPT_DATA },
300 { "CKM_DSA_PARAMETER_GEN", CKM_DSA_PARAMETER_GEN },
301 { "CKM_DH_PKCS_PARAMETER_GEN", CKM_DH_PKCS_PARAMETER_GEN },
302 { "CKM_X9_42_DH_PARAMETER_GEN", CKM_X9_42_DH_PARAMETER_GEN },
303 /*
304 * Values above 0x8000000 (CKM_VENDOR_DEFINED) are represented
305 * as strings with hexadecimal numbers (e.g., "0x8123456").
306 */
307 { NULL, 0 }
308 };
309
310
311 /*
312 * pkcs11_mech_comp - compare two pkcs11_mapping_t structures
313 *
314 * Return a strcmp-like result (positive, zero, or negative).
315 * For use with bsearch(3C) in pkcs11_mech2str().
316 */
317 static int
318 pkcs11_mech_comp(const void *mapping1, const void *mapping2) {
319 return (((pkcs11_mapping_t *)mapping1)->mech -
320 ((pkcs11_mapping_t *)mapping2)->mech);
321 }
322
323
324 /*
325 * pkcs11_mech2str - convert PKCS#11 mech to a string
326 *
327 * Anything below CKM_VENDOR_DEFINED that wasn't in the mapping table
328 * at build time causes NULL to be returned. Anything above it also
329 * returns NULL since we have no way to know its real name.
330 */
331 const char
332 *pkcs11_mech2str(CK_MECHANISM_TYPE mech)
333 {
334 pkcs11_mapping_t target;
335 pkcs11_mapping_t *result = NULL;
336
337 if (mech > CKM_VENDOR_DEFINED) {
338 return (NULL);
339 }
340
341 /* Search for the mechanism number using bsearch(3C) */
342 target.mech = mech;
343 target.str = NULL;
344 result = (pkcs11_mapping_t *)bsearch((void *)&target, (void *)mapping,
345 (sizeof (mapping) / sizeof (pkcs11_mapping_t)) - 1,
346 sizeof (pkcs11_mapping_t), pkcs11_mech_comp);
347 if (result != NULL) {
348 return (result->str);
349 }
350
351 return (NULL);
352 }
353
354 /*
355 * pkcs11_str2mech - convert a string into a PKCS#11 mech number.
356 *
357 * Since there isn't a reserved value for an invalid mech we return
358 * CKR_MECHANISM_INVALID for anything we don't recognise.
359 * The value in mech isn't meaningful in these cases.
360 */
361 CK_RV
362 pkcs11_str2mech(char *mech_str, CK_MECHANISM_TYPE_PTR mech)
363 {
364 int i;
365 int compare_off = 0;
366
367 if (mech_str == NULL)
368 return (CKR_MECHANISM_INVALID);
369
370 if (strncasecmp(mech_str, "0x", 2) == 0) {
371 long long llnum;
372 cryptodebug("pkcs11_str2mech: hex string passed in: %s",
373 mech_str);
374 llnum = strtoll(mech_str, NULL, 16);
375 if ((llnum >= CKM_VENDOR_DEFINED) && (llnum <= UINT_MAX)) {
376 *mech = llnum;
377 return (CKR_OK);
378 } else {
379 return (CKR_MECHANISM_INVALID);
380 }
381 }
382
383 /* If there's no CKM_ prefix, then ignore it in comparisons */
384 if (strncasecmp(mech_str, "CKM_", 4) != 0) {
385 cryptodebug("pkcs11_str2mech: no CKM_ prefix: %s", mech_str);
386 cryptodebug("pkcs11_str2mech: with prefix: CKM_%s", mech_str);
387 compare_off = 4;
388 }
389
390 /* Linear search for a matching string */
391 for (i = 0; mapping[i].str; i++) {
392 if (strcasecmp(&mapping[i].str[compare_off], mech_str) == 0) {
393 *mech = mapping[i].mech;
394 return (CKR_OK);
395 }
396 }
397
398 return (CKR_MECHANISM_INVALID);
399 }
|