2013-06-21 36 views
3

由于在这个问题描述:Openssl C++ get expiry date,有写一个ASN1时间为BIO缓冲区,然后读回到自定义缓冲buf可能性:没有BIO的ASN1_TIME_print功能?

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

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

理想情况下,BIO_new_mem_buf将适合,因为它创建一个使用给定缓冲区作为源的内存中BIO。不幸的是,该函数将给定的缓冲区视为只读,这不是我们想要的。然而,我们可以创建自己的函数(我们称之为BIO_new_mem_buf2)的基础上,BIO_new_mem_bufsource code

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除了一)len参数必须指示给定缓冲区的大小,以及b) BIO是而不是标记为“只读”。

通过上述,您现在应该能够调用:

ASN1_TIME_print(bio, tm) 

,并有足够的时间出现在给定的缓冲区。

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

1

您可以尝试下面的示例代码。它不使用BIO,但应该给出与OP示例相同的输出。如果你不信任ASN1_TIME字符串,你要添加一些错误检查:

  • notBefore->数据> 10个字符
  • 每个字符值“0”之间的“9”年,月,日,小时,分钟
  • 值,第二

您应该测试的类型(即UTC),如果你期望多种类型。

如果您希望输出与使用BIO完全匹配,您还应测试日期/时间是否为GMT,并将其添加到字符串中。见: 的OpenSSL /密码/ ASN 1/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 
}