Функциональность ASN1_TIME_print без BIO?

Как описано в этом вопросе: дата истечения срока действия Openssl C++ получить, есть возможность написать время ASN1 в буфер BIO, а затем прочитать его обратно в пользовательский буфер buf:

BIO *bio;
int write = 0;
bio = BIO_new(BIO_s_mem());
if (bio) {
  if (ASN1_TIME_print(bio, tm))
    write = BIO_read(bio, buf, len-1);
  BIO_free(bio);
}
buf[write]='\0';
return write;

Как этого добиться вообще без использования БИО? Функция ASN1_TIME_print присутствует только тогда, когда OPENSSL_NO_BIO не определена. Есть ли способ записать время непосредственно в заданный буфер?


person eckes    schedule 21.06.2013    source источник


Ответы (2)


Вы можете попробовать пример кода ниже. Он не использует BIO, но должен дать вам тот же результат, что и пример OP. Если вы не доверяете строке ASN1_TIME, вам нужно добавить проверку ошибок для:

  • notBefore->данные> 10 символов
  • каждое значение char находится между «0» и «9»
  • значения года, месяца, дня, часа, минуты, секунды
  • тип

Вы должны проверить тип (например, UTC), если вы ожидаете несколько типов.

Вы также должны проверить, являются ли дата/время GMT или нет, и добавить это в строку, если вы хотите, чтобы выходные данные точно совпадали с использованием BIO. см.: openssl/crypto/asn1/t_x509.c - ASN1_UTCTIME_print или ASN1_GENERALIZEDTIME_print


ASN1_TIME* notBefore = NULL;
int len = 32;
char buf[len];
struct tm tm_time;

notBefore = X509_get_notBefore(x509_cert);

// Format ASN1_TIME  with type UTC into a tm struct
if(notBefore->type == V_ASN1_UTCTIME){
    strptime((const char*)notBefore->data, "%y%m%d%H%M%SZ" , &tm_time);
    strftime(buf, sizeof(char) * len, "%h %d %H:%M:%S %Y", &tm_time);
}

// Format ASN1_TIME with type "Generalized" into a tm struct
if(notBefore->type == V_ASN1_GENERALIZEDTIME){
     // I didn't look this format up, but it shouldn't be too difficult
}
person Steve Miskovetz    schedule 11.10.2016

Я думаю, что это должно быть возможно, по крайней мере, с точки зрения записи времени непосредственно в заданный буфер, но вам все равно нужно будет использовать BIO.

В идеале подойдет BIO_new_mem_buf, учитывая, что он создает BIO в памяти, используя заданный буфер в качестве источника. К сожалению, эта функция рассматривает данный буфер как доступный только для чтения, а это не то, что нам нужно. Однако мы можем создать собственную функцию (назовем ее BIO_new_mem_buf2) на основе BIO_new_mem_buf исходный код:

BIO *BIO_new_mem_buf2(void *buf, int len)
{
    BIO *ret;
    BUF_MEM *b;
    size_t sz;

    if (!buf) {
        BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER);
        return NULL;
    }
    sz = (size_t)len;
    if (!(ret = BIO_new(BIO_s_mem())))
        return NULL;
    b = (BUF_MEM *)ret->ptr;
    b->data = buf;
    b->length = sz;
    b->max = sz;
    return ret;
}

Это то же самое, что и BIO_new_mem_buf, за исключением того, что a) аргумент len должен указывать размер данного буфера, и b)< /em> BIO не помечен как "только для чтения".

С учетом вышеизложенного вы теперь сможете вызывать:

ASN1_TIME_print(bio, tm)

и время появится в вашем заданном буфере.

Обратите внимание, что приведенный выше код не тестировался, поэтому YMMV. Надеюсь это поможет!

person Castaglia    schedule 21.02.2016