如本问题所述: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
时出现。有没有办法将时间直接写入给定的缓冲区?
答案 0 :(得分:2)
您可以尝试下面的示例代码。它不使用BIO,但应该提供与OP的示例相同的输出。如果您不信任ASN1_TIME字符串,则需要为以下内容添加一些错误检查:
如果您需要多种类型,则应测试类型(即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。希望这有帮助!