Added certificate import on key generation.
This commit is contained in:
+22
@@ -205,6 +205,28 @@ int get_object_id(enum enum_slot slot) {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int key_to_object_id(int key) {
|
||||||
|
int object;
|
||||||
|
|
||||||
|
switch(key) {
|
||||||
|
case 0x9a:
|
||||||
|
object = YKPIV_OBJ_AUTHENTICATION;
|
||||||
|
break;
|
||||||
|
case 0x9c:
|
||||||
|
object = YKPIV_OBJ_SIGNATURE;
|
||||||
|
break;
|
||||||
|
case 0x9d:
|
||||||
|
object = YKPIV_OBJ_KEY_MANAGEMENT;
|
||||||
|
break;
|
||||||
|
case 0x9e:
|
||||||
|
object = YKPIV_OBJ_CARD_AUTH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
object = 0;
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
bool set_component_with_len(unsigned char **in_ptr, const BIGNUM *bn, int element_len) {
|
bool set_component_with_len(unsigned char **in_ptr, const BIGNUM *bn, int element_len) {
|
||||||
int real_len = BN_num_bytes(bn);
|
int real_len = BN_num_bytes(bn);
|
||||||
*in_ptr += set_length(*in_ptr, element_len);
|
*in_ptr += set_length(*in_ptr, element_len);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ X509_NAME *parse_name(const char*);
|
|||||||
unsigned char get_algorithm(EVP_PKEY*);
|
unsigned char get_algorithm(EVP_PKEY*);
|
||||||
FILE *open_file(const char*, int);
|
FILE *open_file(const char*, int);
|
||||||
int get_object_id(enum enum_slot slot);
|
int get_object_id(enum enum_slot slot);
|
||||||
|
int key_to_object_id(int key);
|
||||||
bool set_component_with_len(unsigned char**, const BIGNUM*, int);
|
bool set_component_with_len(unsigned char**, const BIGNUM*, int);
|
||||||
bool prepare_rsa_signature(const unsigned char*, unsigned int, unsigned char*,
|
bool prepare_rsa_signature(const unsigned char*, unsigned int, unsigned char*,
|
||||||
unsigned int*, int);
|
unsigned int*, int);
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#ifndef DEBUG_H
|
#ifndef DEBUG_H
|
||||||
#define DEBUG_H
|
#define DEBUG_H
|
||||||
|
|
||||||
#define YKCS11_DBG 0 // General debug, must be either 1 or 0
|
#define YKCS11_DBG 1 // General debug, must be either 1 or 0
|
||||||
#define YKCS11_DINOUT 0 // Function in/out debug, must be either 1 or 0
|
#define YKCS11_DINOUT 0 // Function in/out debug, must be either 1 or 0
|
||||||
|
|
||||||
#define D(x) do { \
|
#define D(x) do { \
|
||||||
|
|||||||
+14
-6
@@ -33,7 +33,7 @@ CK_RV do_store_cert(CK_BYTE_PTR data, CK_ULONG len, X509 **cert) {
|
|||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
#include "debug.h"
|
|
||||||
CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa, CK_ULONG key_len,
|
CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa, CK_ULONG key_len,
|
||||||
CK_BYTE_PTR out, CK_ULONG_PTR out_len) {
|
CK_BYTE_PTR out, CK_ULONG_PTR out_len) {
|
||||||
|
|
||||||
@@ -69,7 +69,6 @@ CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa, CK_
|
|||||||
goto create_empty_cert_cleanup;
|
goto create_empty_cert_cleanup;
|
||||||
|
|
||||||
data_ptr = in + 5;
|
data_ptr = in + 5;
|
||||||
dump_hex(in, in_len, stderr, CK_TRUE);
|
|
||||||
if (*data_ptr != 0x81)
|
if (*data_ptr != 0x81)
|
||||||
goto create_empty_cert_cleanup;
|
goto create_empty_cert_cleanup;
|
||||||
|
|
||||||
@@ -132,10 +131,6 @@ CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa, CK_
|
|||||||
if (X509_set_pubkey(cert, key) == 0) // TODO: there is also X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
|
if (X509_set_pubkey(cert, key) == 0) // TODO: there is also X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
|
||||||
goto create_empty_cert_cleanup;
|
goto create_empty_cert_cleanup;
|
||||||
|
|
||||||
p = in;
|
|
||||||
if ((*out_len = i2d_X509(cert, &p)) == 0)
|
|
||||||
goto create_empty_cert_cleanup;
|
|
||||||
|
|
||||||
// TODO: add more info like issuer?
|
// TODO: add more info like issuer?
|
||||||
tm = ASN1_TIME_new();
|
tm = ASN1_TIME_new();
|
||||||
if (tm == NULL)
|
if (tm == NULL)
|
||||||
@@ -145,6 +140,19 @@ CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa, CK_
|
|||||||
X509_set_notBefore(cert, tm);
|
X509_set_notBefore(cert, tm);
|
||||||
X509_set_notAfter(cert, tm);
|
X509_set_notAfter(cert, tm);
|
||||||
|
|
||||||
|
len = i2d_X509(cert, NULL);
|
||||||
|
if (len < 0)
|
||||||
|
goto create_empty_cert_cleanup;
|
||||||
|
|
||||||
|
if (len > *out_len) {
|
||||||
|
rv = CKR_BUFFER_TOO_SMALL;
|
||||||
|
goto create_empty_cert_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = in;
|
||||||
|
if ((*out_len = i2d_X509(cert, &p)) == 0)
|
||||||
|
goto create_empty_cert_cleanup;
|
||||||
|
|
||||||
/* TODO REMOVE THIS */
|
/* TODO REMOVE THIS */
|
||||||
BIO *STDout = BIO_new_fp(stderr, BIO_NOCLOSE);
|
BIO *STDout = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||||
|
|
||||||
|
|||||||
+44
-9
@@ -1,13 +1,15 @@
|
|||||||
#include "token_vendors.h"
|
#include "token_vendors.h"
|
||||||
#include "yubico_token.h"
|
#include "yubico_token.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include "debug.h"
|
||||||
static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE key, CK_ULONG key_len) {
|
static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE key, CK_ULONG key_len) {
|
||||||
// TODO: make a function in ykpiv for this
|
// TODO: make a function in ykpiv for this
|
||||||
unsigned char in_data[5];
|
unsigned char in_data[5];
|
||||||
unsigned char data[1024];
|
unsigned char data[1024];
|
||||||
unsigned char templ[] = {0, YKPIV_INS_GENERATE_ASYMMERTRIC, 0, 0};
|
unsigned char templ[] = {0, YKPIV_INS_GENERATE_ASYMMERTRIC, 0, 0};
|
||||||
|
unsigned char *certptr;
|
||||||
unsigned long recv_len = sizeof(data);
|
unsigned long recv_len = sizeof(data);
|
||||||
unsigned long received = 0;
|
int len_bytes;
|
||||||
int sw;
|
int sw;
|
||||||
|
|
||||||
CK_RV rv;
|
CK_RV rv;
|
||||||
@@ -21,15 +23,27 @@ static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE
|
|||||||
|
|
||||||
switch(key_len) {
|
switch(key_len) {
|
||||||
case 2048:
|
case 2048:
|
||||||
|
if (rsa == CK_TRUE)
|
||||||
in_data[4] = YKPIV_ALGO_RSA2048;
|
in_data[4] = YKPIV_ALGO_RSA2048;
|
||||||
|
else
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1024:
|
case 1024:
|
||||||
|
if (rsa == CK_TRUE)
|
||||||
in_data[4] = YKPIV_ALGO_RSA1024;
|
in_data[4] = YKPIV_ALGO_RSA1024;
|
||||||
|
else
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 256:
|
case 256:
|
||||||
|
if (rsa == CK_FALSE)
|
||||||
in_data[4] = YKPIV_ALGO_ECCP256;
|
in_data[4] = YKPIV_ALGO_ECCP256;
|
||||||
|
else
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -40,15 +54,36 @@ static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE
|
|||||||
sw != 0x9000)
|
sw != 0x9000)
|
||||||
return CKR_DEVICE_ERROR;
|
return CKR_DEVICE_ERROR;
|
||||||
|
|
||||||
|
// Create a new empty certificate for the key
|
||||||
/* to drop the 90 00 and the 7f 49 at the start */
|
recv_len = sizeof(data);
|
||||||
received += recv_len - 4;
|
if ((rv = do_create_empty_cert(data, recv_len, rsa, key_len, data, &recv_len)) != CKR_OK)
|
||||||
|
|
||||||
|
|
||||||
/* Create a new empty certificate for the key */
|
|
||||||
if ((rv = do_create_empty_cert(data, recv_len, rsa, key_len, in_data, &recv_len)) != CKR_OK)
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
|
if (recv_len < 0x80)
|
||||||
|
len_bytes = 1;
|
||||||
|
else if (recv_len < 0xff)
|
||||||
|
len_bytes = 2;
|
||||||
|
else
|
||||||
|
len_bytes = 3;
|
||||||
|
|
||||||
|
certptr = data;
|
||||||
|
memmove(data + len_bytes + 1, data, recv_len);
|
||||||
|
|
||||||
|
*certptr++ = 0x70;
|
||||||
|
certptr += set_length(certptr, recv_len);
|
||||||
|
certptr += recv_len;
|
||||||
|
*certptr++ = 0x71;
|
||||||
|
*certptr++ = 1;
|
||||||
|
*certptr++ = 0; /* certinfo (gzip etc) */
|
||||||
|
*certptr++ = 0xfe; /* LRC */
|
||||||
|
*certptr++ = 0;
|
||||||
|
|
||||||
|
dump_hex(data, (size_t)(certptr - data), stderr, CK_TRUE);
|
||||||
|
|
||||||
|
// Store the certificate into the token
|
||||||
|
if (ykpiv_save_object(state, key_to_object_id(key), data, (size_t)(certptr - data)) != YKPIV_OK)
|
||||||
|
return CKR_DEVICE_ERROR;
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user