CK_FUNCTION_LIST *
p11_init(void)
{
	CK_RV            rv;
	CK_RV		 (*pfoo)();
	char		 *loc1_lib = "/usr/lib/pkcs11/PKCS11_API.so64";
	char		 *loc2_lib = "libopencryptoki.so";
	CK_FUNCTION_LIST *funcs = NULL;


	p11_lib = dlopen(loc1_lib, RTLD_NOW);
	if (p11_lib != NULL)
		goto get_list;

	p11_lib = dlopen(loc2_lib, RTLD_NOW);
	if (p11_lib == NULL) {
		print_error("Couldn't get a handle to the PKCS#11 library.");
		return NULL;
	}

get_list:
	pfoo = (CK_RV (*)())dlsym(p11_lib,"C_GetFunctionList");
	if (pfoo == NULL) {
		print_error("Couldn't get the address of the C_GetFunctionList routine.");
		dlclose(p11_lib);
		return NULL;
	}

	rv = pfoo(&funcs);
	if (rv != CKR_OK) {
		p11_error("C_GetFunctionList", rv);
		dlclose(p11_lib);
		return NULL;
	}

	rv = funcs->C_Initialize(NULL_PTR);
	if (rv != CKR_OK) {
		p11_error("C_Initialize", rv);
		dlclose(p11_lib);
		return NULL;
	}

	if (v_flag > 1)
		printf("PKCS#11 library initialized\n");

	return funcs;
}
Exemple #2
0
int main(int argc, char **argv)
{
    CK_ULONG          nslots;
    CK_SLOT_ID        *pslots = NULL;
    CK_FUNCTION_LIST  *funcs = NULL;
    CK_UTF8CHAR_PTR   opt_pin = NULL;
    CK_ULONG          opt_pin_len = 0;
    CK_RV             rc;
    CK_ULONG          opt_slot = -1;
    CK_SESSION_HANDLE h_session;
    char *opt_module = NULL, *opt_dir = NULL;
    /* struct sockaddr_un sockaddr; */
    int long_optind = 0;
    int fd, verbose = 0;
    key_id_t *rsa_keys, *ec_keys;
    CK_ULONG rsa_len = 0, ec_len = 0, i;

    init_crypto();

    while (1) {
        char c = getopt_long(argc, argv, "d:hp:s:m:v",
                             options, &long_optind);
        if (c == -1)
            break;
        switch (c) {
            case 'd':
                opt_dir = optarg;
                break;
            case 'p':
                opt_pin = (CK_UTF8CHAR_PTR) strdup(optarg);
                if(opt_pin) {
                    opt_pin_len = strlen(optarg);
                }
                break;
            case 's':
                opt_slot = (CK_SLOT_ID) atoi(optarg);
                break;
            case 'm':
                opt_module = optarg;
                break;
            case 'v':
                verbose = 1;
                break;
            case 'h':
            default:
                print_usage_and_die(app_name, options, option_help);
        }
    }

    rc = pkcs11_load_init(opt_module, opt_dir, stderr, &funcs);
    if (rc != CKR_OK) {
        return rc;
    }

    rc = pkcs11_get_slots(funcs, stderr, &pslots, &nslots);
    if (rc != CKR_OK) {
        return rc;
    }

    if(opt_slot == -1) {
        if(nslots < 1) {
            /* No slots */
            return -1;
        } else {
            opt_slot = pslots[0];
        }
    } else {
        /* Check selected slot is in pslots */
    }

    fprintf(stderr, "Slot: %ld\n", opt_slot);
    rc = pkcs11_login_session(funcs, stderr, opt_slot, &h_session,
                              CK_TRUE, CKU_USER, opt_pin, opt_pin_len);
    if (rc != CKR_OK) {
        show_error(stderr, "Login", rc);
        return rc;
    }
    
    load_keys(funcs, h_session, CKK_RSA, &rsa_keys, &rsa_len);
    load_keys(funcs, h_session, CKK_EC,  &ec_keys,  &ec_len);


    /* fd = nw_unix_server("pkcs11d.sock", &sockaddr, 0, 0, 0, 64); */
    /* close(fd); */
    fd = nw_tcp_server(1234, 0, 64);
    
    do {
        struct sockaddr address;
        socklen_t a_len = sizeof(address);
        int s = accept(fd, &address, &a_len);
        BIO *b = BIO_new_socket(s, BIO_NOCLOSE);
        BIO *buf = BIO_new(BIO_f_buffer());
        b = BIO_push(buf, b);
        char buffer[4096], sig[4096], keyid[KEY_ID_SIZE + 1];
        int l, slen = 0, plen = 0;
        CK_KEY_TYPE type;
        CK_ATTRIBUTE_TYPE operation;
        EVP_PKEY *pkey = NULL;

        l = BIO_gets(b, buffer, sizeof(buffer));
        if(l <= 0) {
            fprintf(stderr, "Error reading query line\n");
            goto end;
        }

        if(strncmp(buffer, "POST /sign/rsa/", 15) == 0) {
            memcpy(keyid, buffer + 15, KEY_ID_SIZE - 1);
            type = CKK_RSA;
            operation = CKA_SIGN;
        } else if(strncmp(buffer, "POST /decrypt/rsa/", 18) == 0) {
            memcpy(keyid, buffer + 18, KEY_ID_SIZE - 1);
            type = CKK_RSA;
            operation = CKA_DECRYPT;
        } else if(strncmp(buffer, "POST /sign/ec/", 14) == 0) {
            memcpy(keyid, buffer + 14, KEY_ID_SIZE - 1);
            type = CKK_EC;
            operation = CKA_SIGN;
        } else {
            goto end;
        }
        keyid[KEY_ID_SIZE] = '\0';

        l = BIO_gets(b, buffer, sizeof(buffer));
        if((l <= 0) || strncmp(buffer, "Content-Length: ", 16) != 0) {
            fprintf(stderr, "Invalid content length line = %s\n", buffer);
            goto end;
        }
        plen = atoi(buffer + 16);
        l = BIO_gets(b, buffer, sizeof(buffer));
        l = BIO_read(b, buffer, plen);
        if(l < plen) {
            fprintf(stderr, "Error reading payload\n");
            goto end;
        }


        if(type == CKK_RSA) {
            for(i = 0; (i < rsa_len) && (pkey == NULL); i++) {
                if(strncmp(rsa_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) {
                    pkey = rsa_keys[i].key;
                }
            }
        } else if(type == CKK_EC) {
            for(i = 0; (i < ec_len) && (pkey == NULL); i++) {
                if(strncmp(ec_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) {
                    pkey = ec_keys[i].key;
                }
            }
        }
        if(pkey == NULL) {
            fprintf(stderr, "Key not found\n");
            goto end;
        } else if(verbose) {
            fprintf(stderr, "Key '%s'found\n", keyid);
        }
        
        if(type == CKK_RSA && operation == CKA_SIGN) {
            if(verbose) {
                fprintf(stderr, "RSA signature operation requested\n");
            }
            l = RSA_private_encrypt(plen, (unsigned char *)buffer, (unsigned char *)sig,
                                    EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING);
        } else if(type == CKK_RSA && operation == CKA_DECRYPT) {
            if(verbose) {
                fprintf(stderr, "RSA decryption operation requested\n");
            }
            l = RSA_private_decrypt(plen, (unsigned char *)buffer, (unsigned char *)sig,
                                    EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING);
        } else if (type == CKK_EC && operation == CKA_SIGN) {
            unsigned char *ptr = (unsigned char *)sig;
            ECDSA_SIG *s = ECDSA_do_sign((unsigned char *)buffer, plen, EVP_PKEY_get1_EC_KEY(pkey));
            l = i2d_ECDSA_SIG(s, &ptr);
            ECDSA_SIG_free(s);
        } else {
            if(verbose) {
                fprintf(stderr, "Invalid operation requested\n");
            }
            goto end;
        }

        slen = l;
        if(l <= 0) {
            if(verbose) {
                fprintf(stderr, "Error unsuccessful\n");
            }
            goto end;
        } else if(verbose) {
            fprintf(stderr, "Operation successful\n");
        }

        BIO_printf(b, "200 Ok\r\n");
        BIO_printf(b, "Content-Length: %d\r\n\r\n", slen);

        l = BIO_write(b, sig, slen);
        BIO_flush(b);

        i= 0;
        /*
        for(i = 0; i < rsa_len; i++) {
            BIO_write(b, rsa_keys[i].id, KEY_ID_SIZE);
            BIO_write(b, "\n", 1);
            PEM_write_bio_RSAPrivateKey(b, EVP_PKEY_get1_RSA(rsa_keys[i].key), NULL, NULL, 0, NULL, NULL);
        }
        for(i = 0; i < ec_len; i++) {
            BIO_write(b, ec_keys[i].id, KEY_ID_SIZE);
            BIO_write(b, "\n", 1);
            PEM_write_bio_ECPrivateKey(b, EVP_PKEY_get1_EC_KEY(ec_keys[i].key), NULL, NULL, 0, NULL, NULL);
        }
        */


    end:
        close(s);
        BIO_free(b);
    } while(1);

    close(fd);

    if(opt_pin) {
        funcs->C_CloseAllSessions(opt_slot);
        free(opt_pin);
    }

    rc = funcs->C_Finalize(NULL);
    if (rc != CKR_OK) {
        show_error(stderr, "C_Finalize", rc);
        return rc;
    }
    
    return rc;
}
Exemple #3
0
int mechanisms(int argc, char **argv)
{
    CK_ULONG          nslots, islot;
    CK_SLOT_ID        *pslots = NULL;
    CK_FUNCTION_LIST  *funcs = NULL;
    CK_RV             rc;
    CK_ULONG          opt_slot = -1;
    char *opt_module = NULL, *opt_dir = NULL;
    int long_optind = 0;

    while (1) {
        char c = getopt_long(argc, argv, "d:hs:m:",
                             options, &long_optind);
        if (c == -1)
            break;
        switch (c) {
            case 'd':
                opt_dir = optarg;
                break;
            case 's':
                opt_slot = (CK_SLOT_ID) atoi(optarg);
                break;
            case 'm':
                opt_module = optarg;
                break;
            case 'h':
            default:
                print_usage_and_die(app_name, options, option_help);
        }
    }

    rc = pkcs11_load_init(opt_module, opt_dir, stdout, &funcs);
    if (rc != CKR_OK) {
        return rc;
    }

    rc = pkcs11_get_slots(funcs, stdout, &pslots, &nslots);
    if (rc != CKR_OK) {
        return rc;
    }

    if(opt_slot != -1) {
        CK_ULONG i = 0;
        while (i < nslots && pslots[i] != opt_slot) {
            i++;
        }
        if (i == nslots) {
            fprintf(stderr, "Unknown slot '%lu'\n", opt_slot);
            return -1;            
        }

        pslots[0] = opt_slot;
        nslots = 1;
    }

    for (islot = 0; islot < nslots; islot++) {
            do_GetTokenMech(funcs, pslots[islot]);
    }

    rc = funcs->C_Finalize(NULL);
    if (rc != CKR_OK) {
        show_error(stdout, "C_Finalize", rc);
        return rc;
    }

    return rc;
}
int
main(int argc, char *argv[])
{
	int               opt, c_flag = 0;
	CK_SLOT_ID	  slot_id = 0;
	char		 *so_pin = NULL, *user_pin = NULL, *data_store = NULL;

	CK_FUNCTION_LIST *funcs;
	CK_ULONG	  slot_count;
	CK_SESSION_HANDLE sess;
	CK_RV		  rv;
	struct object    *objs_to_migrate = NULL, *tmp, *to_free;
	int		  exit_code = 0, rc;
	
	lib_csulcca = dlopen("libcsulcca.so", (RTLD_GLOBAL | RTLD_NOW));
	if (lib_csulcca == NULL) {
		print_error("Couldn't get a handle to the CCA library.");
		return NULL;
	}

	CSNDKTC = dlsym(lib_csulcca, "CSNDKTC_32");
	CSNBKTC = dlsym(lib_csulcca, "CSNBKTC_32");	

	while ((opt = getopt(argc, argv, "c:d:s:u:nvh")) != -1) {
		switch (opt) {
		case 'c':
			c_flag++;
			slot_id = atoi(optarg);
			break;

		case 'd':
			data_store = strdup(optarg);
			break;

		case 's':
			so_pin = strdup(optarg);
			break;

		case 'u':
			user_pin = strdup(optarg);
			break;

		case 'n':
			n_flag++;
			break;

		case 'v':
			v_flag++;
			break;

		case 'h':
			usage(argv[0]);
			return 0;

		default:
			usage(argv[0]);
			return 1;
		}
	}

	if (!c_flag || !data_store || !so_pin || !user_pin) {
		usage(argv[0]);
		return 1;
	}

	if (n_flag)
		printf("Dry-run of migration in progress\n");

	funcs = p11_init();
	if (!funcs) {
		return 2;
	}

	rv = funcs->C_GetSlotList(TRUE, NULL_PTR, &slot_count);
	if (rv != CKR_OK) {
		p11_error("C_GetSlotList", rv);
		exit_code = 3;
		goto finalize;
	}

	if (slot_id >= slot_count) {
		print_error("%lu is not a valid slot ID.", slot_id);
		exit_code = 4;
		goto finalize;
	}
	if (v_flag > 1)
		printf("Slot id %lu is valid\n", slot_id);

	/* Open a r/w session */
	rv = funcs->C_OpenSession(slot_id, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &sess);
	if (rv != CKR_OK) {
		p11_error("C_OpenSession", rv);
		exit_code = 5;
		goto finalize;
	}
	if (v_flag > 1)
		printf("PKCS#11 r/w session opened\n");

	/* Login as the SO just validate the supplied pin */
	rv = funcs->C_Login(sess, CKU_SO, (CK_BYTE *)so_pin, strlen(so_pin));
	if (rv != CKR_OK) {
		p11_error("C_Login (SO)", rv);
		exit_code = 6;
		goto finalize;
	}
	if (v_flag > 1)
		printf("PKCS#11 SO login successful\n");

	/* Logout the SO */
	rv = funcs->C_Logout(sess);
	if (rv != CKR_OK) {
		p11_error("C_Logout", rv);
		exit_code = 7;
		goto finalize;
	}

	/* Login as the USER to validate the supplied pin and do the migration */
	rv = funcs->C_Login(sess, CKU_USER, (CK_BYTE *)user_pin, strlen(user_pin));
	if (rv != CKR_OK) {
		p11_error("C_Login (USER)", rv);
		exit_code = 8;
		goto finalize;
	}
	if (v_flag > 1)
		printf("PKCS#11 USER login successful\n");

	/* Find the affected PKCS#11 objects */
	rc = find_opaque_objects(funcs, sess, &objs_to_migrate);
	if (rc) {
		exit_code = 9;
		goto close;
	}

	/* XXX Print status: migrating X pub keys, X priv keys, X 3DES keys... */

	/* Use the CCA lib to migrate them to the new master key */
	rv = migrate_objects(objs_to_migrate);
	if (rv != CKR_OK) {
		exit_code = 10;
		goto close;
	}

	/* XXX Print status */

	/* Delete the old PKCS#11 objects (or just attribs if possible) and replace with the
	 * migrated data */
	rc = replace_objects(funcs, sess, objs_to_migrate);
	if (rc) {
		exit_code = 11;
		goto close;
	}

	/* XXX Print status: X objects successfully migrated */

	/* Free the list of PKCS#11 objects */
	for (to_free = objs_to_migrate; to_free; to_free = tmp) {
		tmp = to_free->next;
		free(to_free->opaque_attr);
		free(to_free);
	}

	/* Migrate the keys used to encrypt the data store */
	rc = migrate_master_keys(so_pin, user_pin, data_store);
	if (rc) {
		exit_code = 12;
		goto close;
	}

close:
	funcs->C_CloseSession(sess);
finalize:
	p11_fini(funcs);
	return exit_code;
}