i2d_X509_REQ_INFO неправильно конвертирует структуру req_info - PullRequest
0 голосов
/ 01 октября 2018

Мы работаем над токенами для генерации 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 );

1 Ответ

0 голосов
/ 03 октября 2018

Похоже, что вы пропустили часть соответствующей документации (что, по общему признанию, происходит очень легко):

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
...