Please tell me how to print the values of extensions in x.509
HTML语言: Codee#23000
my x.509 's user extensions were defined as follows:
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
D8:F0:12:EA:0D:67:55:96:C9:8E:A4:36:9E:62:84:7F:6F:41:0C:DB
X509v3 Authority Key Identifier:
keyid:C4:33:98:59:50:6B:CC:48:5A:4A:D开发者_StackOverflow中文版7:5B:C0:A7:7C:37:DE:15:24:33
SEwVersion:
..0.2
SEww:
..0X5699
please tell me how to extract the value of extensions and print them in screen in a ascii string mode, namely, we can indentify them normally, just like:
*print format *
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
D8:F0:12:EA:0D:67:55:96:C9:8E:A4:36:9E:62:84:7F:6F:41:0C:DB
X509v3 Authority Key Identifier:
keyid:C4:33:98:59:50:6B:CC:48:5A:4A:D7:5B:C0:A7:7C:37:DE:15:24:33
SEVersion:
0.2 // no prefix like ".."
SE:
0X5699 // no prefix like ".."
and another problem is:
SEwVersion:
..0.2
SEww:
0...version..0X5699
then how I can get and print to screen like this:
SEwVersion:
0.2 //no prefix ".."
SEww:
version 0X5699// no "..."and ".."
and my codes as follows:
int Ext_count = X509_get_ext_count(cert);
for (int k=0; k <Ext_count; k++ ){
X509_EXTENSION* ex = X509_get_ext(cert, k);
if( ex == NULL )
continue;
OBJ_obj2txt((char *)buf, 100, ex->object, 0);
printf("name = %s\n", buf);
if (k>=Ext_count-2)
//I distinguish basic extensions and my added extensions like this , so it is not good methode, please tell me how to ...
{
ASN1_OCTET_STRING* octet_str = X509_EXTENSION_get_data(ex);
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);
}
else
{
BIO *bio = BIO_new(BIO_s_mem());
if(!X509V3_EXT_print(bio, ex, 0, 0)) // read the text of this extention
M_ASN1_OCTET_STRING_print(bio,ex->value);
len = BIO_read(bio, buf, 200);// here buffer contain the text, len the lenght of it.
buf[len] = '\0'; // add the EOT sign, buffer contain a readable text.
BIO_free(bio);
printf("value = %s\n", buf);
}
Thank you very much for your kindly help in advance.
Here it goes an example for read and print the Authority Key Id from some certificate:
FILE *arq = fopen("<path to your certificate in PEM format>","rw");
int next;
X509 *cert;
cert = PEM_read_X509(arq,NULL,NULL, NULL);
X509_EXTENSION *ext;
next = X509_get_ext_count(cert);
for (int i=0;i<next;i++)
{
ext = X509_get_ext(cert, i);
int nid = OBJ_obj2nid(ext->object);
if(nid == NID_authority_key_identifier)
{
AUTHORITY_KEYID *authKeyId = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext);
//converting to hex
std::string data;
char *hex_data = new char[authKeyId->keyid->length*2 +1];
int j = 0;
for(int i = 0; i < authKeyId->keyid->length; i++)
{
sprintf(&hex_data[j], "%02X", authKeyId->keyid->data[i]);
j+=2;
}
hex_data[j] = '\0';
data = hex_data;
delete[] hex_data;
cout << "Authority Key Id: " << data << endl;
}
}
Thanks, Giovani your answer solves the major problem, the only challenge I faced was getting hex data. Managing and handling length in following code part was crucial and can lead to extraneous/empty data.
char *hex_data = new char[authKeyId->keyid->length*2 +1];
int j = 0;
for(int i = 0; i < authKeyId->keyid->length; i++)
{
sprintf(&hex_data[j], "%02X", authKeyId->keyid->data[i]);
j+=2;
}
hex_data[j] = '\0';
This can be easily handled using "hex_to_string" API which library already provides. Following is the example of how to use this API.
int loc = X509_get_ext_by_NID(cert, NID_subject_key_identifier,-1);
X509_EXTENSION *ext = X509_get_ext(cert, loc);
if (ext) {
const unsigned char* octet_str_data = ext->value->data;
long xlen;
int tag, xclass;
int ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, ext->value->length);
char* skid = hex_to_string(octet_str_data, xlen);
if(skid != nullptr)
{
certificate_skid.assign(skid);
free(skid);
}
}
Hope it will help future readers.
精彩评论