没有BIO的ASN1_TIME_print功能?

时间:2013-06-21 12:35:36

标签: c openssl

如本问题所述:Openssl C++ get expiry date,可以将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;

如果不使用BIO,怎么能实现? ASN1_TIME_print函数仅在未定义OPENSSL_NO_BIO时出现。有没有办法将时间直接写入给定的缓冲区?

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:0)

我认为这应该是可能的,至少在将时间直接写入给定缓冲区方面是这样 - 但你仍然需要使用BIO。

理想情况下,BIO_new_mem_buf适合,因为它使用给定的缓冲区作为源创建内存中的BIO。不幸的是,该函数将给定缓冲区视为只读,这不是我们想要的。但是,我们可以根据BIO_new_mem_buf2 source code创建我们自己的函数(我们称之为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) BIO 标记为“只读”。

通过上述内容,您现在应该可以致电:

ASN1_TIME_print(bio, tm)

并将时间显示在您指定的缓冲区中。

注意我还没有测试过上面的代码,所以YMMV。希望这有帮助!