2013-06-21 37 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 
}