3

如本问题所述: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有没有办法将时间直接写入给定的缓冲区?

4

2 回答 2

4

您可以尝试下面的示例代码。它不使用 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
}
于 2016-10-11T23:19:05.447 回答
0

我认为这应该是可能的,至少在将时间直接写入给定缓冲区方面——但你仍然需要使用 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) BIO标记为“只读”。

有了以上内容,您现在应该可以调用:

ASN1_TIME_print(bio, tm)

并让时间出现在您给定的缓冲区中。

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

于 2016-02-21T22:44:28.677 回答