OpenSSL获取证书扩展

5
我将使用openssl来解析X509证书。 我已经成功获取了扩展信息,但是我不知道如何提取扩展值。
我正在使用以下代码:
  X509_EXTENSION *extension =  sk_X509_EXTENSION_pop(exts);
  int critical =  X509_EXTENSION_get_critical(extension);

  ASN1_OBJECT *obj = extension-> object;
  ln = OBJ_nid2ln(OBJ_obj2nid(obj));
  if( !ln ) ln = "";
  OBJ_obj2txt(objbuf,sizeof(objbuf),obj,1);
  int nid = OBJ_txt2nid(ln);  

这段代码告诉我扩展是否关键,并给出了扩展的nid。
我认为可以通过以下方式获得值:
ASN1_OCTET_STRING *data= X509_EXTENSION_get_data(extension);
但是我不确定如何处理检索到的"data"对象。数据对象应该是DER编码的。有任何关于获取扩展数据的想法吗?
编辑: 如此建议在这里,我正在尝试执行:
ASN1_OCTET_STRING* octet_str = X509_EXTENSION_get_data(extension);
const unsigned char* octet_str_data = octet_str->data;
long xlen;
int tag, xclass;
int ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, octet_str->length);
printf(@"value: %s\n", octet_str_data);

但是解码后得到的字符串与之前的字符串相同 - 类似于:4Á˃◊∫Ns∑äP∂W≠%£A


我认为提供一些示例证书和编译正常的代码,只是没有正确显示扩展值,会非常有帮助。 - ThiefMaster
我正在进行一个iOS项目,而且已经为iOS编译了openssl。如果需要的话,我可以添加一个链接。 - Maggie
iOS?你真的在使用C还是ObjC? - ThiefMaster
openssl是一种C库,因此可以轻松地包含在iOS中。有关openssl的代码是纯C代码。 - Maggie
1
@Maggie:顺便说一下,我感同身受。OpenSSL API是我曾经不幸使用过的最糟糕的API。它是一个可憎的东西,我很高兴在处理完我的有限用例后离开了它。 - Roger Dahl
3个回答

1

这非常有趣。我一直在观察对话的进展您提供的链接,以及这里,我同意Roger Dahl在他回答勘误中的评论:

看起来你正在寻求一个通用的解决方案,以提取x509v3扩展中的信息。正如这个问题的标题所述,它仅涉及解码单个OCTET STRING的特殊情况。除此之外,我只能指向@Francois的原始建议,即使用外部ASN.1解析器,例如SNACClibtasn1并查看OpenSSL源代码(大约在crypto/asn1/asn1_par.c:135附近)。

(链接添加为本人)

问题在于你试图使用一种模态扩展模型,这种模型通常无法很好地处理。这个答案提供了一个很好的概述,说明了它的工作原理。至于其他部分的答案,我同意他的观察,即当文档无法解决问题时,阅读源代码是最好的解决方案。


感謝您的建議,我已經查看了SNACC,但目前我還是堅持使用openssl並採用Felipe建議的解決方案。 - Maggie

1

如果我处在你的位置,我会认真考虑使用专用的ASN.1库来解码证书。让OpenSSL发挥其擅长的领域,即根据信任链验证您的证书。一旦确定您拥有了一个好的证书,将其传递给ASN.1库并让它处理剩下的部分。(SNACC看起来不错。)请注意,整个证书本身都是使用ASN.1编码的,因此您用于处理v3扩展的相同库也可用于处理整个证书。


谢谢你的建议,我看了一下SNACC,但目前我还是坚持使用openssl,并采用Felipe提出的解决方案。 - Maggie

1

如果您想要一个文本表示,可以使用内存BIO。我已经在this线程中回答了如何为密钥用途扩展执行此操作,但对于每个扩展来说,执行此操作的方式都是相同的。

敬礼。


1
根据这个链接:BIO是一种I/O抽象,它可以隐藏应用程序的许多底层I/O细节。如果应用程序使用BIO进行其I/O操作,则可以透明地处理SSL连接、未加密的网络连接和文件I/O。 - Fauth
1
换句话说,BIO可作为数据流传输到任何I/O,包括内存本身。 因此,内存BIO只是与内存通信的流。 BIO也可以通过BIO_push()以非常有用的方式链接在一起,如此处所述。 - Fauth
1
这个有效,非常感谢你,这是你的200声望值 :) - Maggie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接