Мы работаем над токенами для генерации CSR (запросов на подпись сертификатов). Keypair генерирует отлично в токене, но мы не можем получить правильный CSR.
Я пытаюсь создать запрос сертификата X509, подписанный внутри смарт-карты, используя интерфейс PKCS11. Я использую openssl-1.0.2.
Для выполнения этой задачи мне необходимо выполнить следующие шаги:
1, создайте запрос сертификата (X509_new)
2, загрузить открытый ключ (X509_REQ_set_pubkey)
3, установите имя субъекта и расширения по мере необходимости
4, экспортировать структуру req_info (i2d_X509_REQ_INFO)
5, подпишите эту структуру, используя PKCS11
К сожалению, созданный запрос не содержит действительной подписи. После более внимательного изучения вызовов openssl я заметил, что буфер, экспортированный с использованием функции i2d_X509_REQ_INFO, не содержит правильно закодированной структуры.
Может ли кто-нибудь мне помочь, что я делаю неправильно или какой параметр структуры я забыл инициализировать?
Relevant part of the code:
...
X509_REQ *req;
X509_NAME *subj;
if (!(req = X509_REQ_new())) {
printf("Unable to initialize X509_REQ structure\n");
return -1;
}
RSA *rsa;
rsa = RSA_new();
rsa->e = BN_bin2bn( (unsigned char *) pub_publicExponent, (int) 3, NULL );
rsa->n = BN_bin2bn( (unsigned char *) modulus, (int) (pub_modulusbits/8), NULL );
if( (pkey = EVP_PKEY_new()) == NULL ) {
printf("Unable to initialize PKEY structure\n");
return -1;
}
EVP_PKEY_assign_RSA( pkey , rsa );
X509_REQ_set_pubkey(req, pkey);
subj=X509_REQ_get_subject_name(req);
X509_NAME_add_entry_by_txt(subj,"C",
MBSTRING_ASC, (unsigned char *)"SK", -1, -1, 0);
X509_NAME_add_entry_by_txt(subj,"CN",
MBSTRING_ASC, (unsigned char *)"Test", -1, -1, 0);
int datasig_len;
unsigned char *tobesigned;
datasig_len = i2d_X509_REQ_INFO( req->req_info, NULL );
tobesigned = (unsigned char *) malloc( datasig_len );
if( !tobesigned ) {
printf("Unable to alloc mem buffer\n");
return -1;
}
int zzz = i2d_X509_REQ_INFO( req->req_info, &tobesigned );
Похоже, вы пропустили часть соответствующая документация (что, по общему признанию, происходит очень легко):
i2d_X509 () кодирует структуру, на которую указывает x, в формат DER. Если
out — это не NULL, это записывает закодированные данные DER в буфер в * out,
и увеличивает его, чтобы указать после только что записанных данных. Если возвращение
значение отрицательно, произошла ошибка, в противном случае возвращается длина
закодированных данных.
(Обратите внимание, что этот фрагмент принимает i2d_X509()
в качестве примера, но он работает так же для i2d_X509_REQ_INFO()
)
Прежде чем ссылаться на i2d
функция, вы должны хранить значение tobesigned
так что вы можете обратиться к нему позже.
Воссоздавая ваш пример, он, кажется, содержит действительное представление вашей структуры в формате DER, так как он, кажется, идет в обратном направлении без проблем. Это иллюстрируется следующим фрагментом:
unsigned char *ptr = tobesigned;
int zzz = i2d_X509_REQ_INFO( req->req_info, &ptr );
const unsigned char *ptr2 = tobesigned;
X509_REQ_INFO *deser = d2i_X509_REQ_INFO(NULL, &ptr2, zzz);
printf("Result of i2d|d2i_X509_REQ_INFO: \n"" zzz = %d\n"" tobesigned = 0x%p\n"" ptr = 0x%p\n"" ptr2 = 0x%p\n"" deser = 0x%p\n",
zzz, tobesigned, ptr, ptr2, deser);
Это дает:
Result of i2d|d2i_X509_REQ_INFO:
zzz = 198
tobesigned = 0x0x7fd09c403010
ptr = 0x0x7fd09c4030d6
ptr2 = 0x0x7fd09c4030d6
deser = 0x0x7fd09c402f60
Других решений пока нет …