Re: Parsing counter signatures - HELP - (UPDATED)
Thank you Jimmy and Stephen! Thanks to your answer, I've finally been able to parse countersignatures at any depth! Regards, Massimiliano Ziccardi On Tue, May 20, 2008 at 5:43 PM, Dr. Stephen Henson [EMAIL PROTECTED] wrote: On Tue, May 20, 2008, Massimiliano Ziccardi wrote: I'm sure OpenSSL is able to parse more than one counter signature per signature. Can pleas some OpenSSL expert tell me how to do it? I think the code I sent in the previous e-mail should be close to the solution. I just need to know how to get the other counter signatures (I already did in Java with Bouncycastle, and it has been straightforward). I've searched through the net for some documentation, but, as stated on the site, the OpenSSL documentation is very incomplete, and I couldn't find any useful information. Unfortunately the attribute handling functions are undocumented at present. They opearate in a manner similar to the documented X509_NAME functions though. This is an outline of what you do If you call PKCS7_get_attributes() you will get back a STACK_OF(X509_ATTRIBUTE). Using that you can look through it using the attribute utility functions. int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, int lastpos); You loop round calling X509at_get_attr_by_NID() to retrieve the index of each countersignature attribute, you get -1 when no more can be found. You set lastpos to the last index or -1 initially. For each index you can get the corresponding attribute with: X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); Then for each X509_ATTRIBUTE you can retrieve the count of attributes with X509_ATTRIBUTE_count(). Then each individual using: void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, void *data); You set idx to the index of each one (starting from zero) atrtype to V_ASN1_SEQUENCE and you get back an ASN1_STRING structure or NULL if the type isn't a SEQUENCE: that shouldn't happen unless the countersignature is malformed. The for each string you parse the countersignature as before. Steve. -- Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage OpenSSL project core developer and freelance consultant. Homepage: http://www.drh-consultancy.demon.co.uk __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Parsing counter signatures - HELP - (UPDATED)
Hi all. I've been able to parse the first counter signature of each signature. At the end of this e-mail, you'll find the code I use to parse the file (no error handling, it's just a working snippet). Attached you'll find my test P7M. The signature/countersignature tree is as follows: SIGNATURE 1 COUNTER SIGNATURE 1 COUNTER SIGNATURE 2 SIGNATURE 2 COUNTER SIGNATURE 1 Can someone please give me an advice about the changes I've to make to the following code to parse the COUNTER SIGNATURE 2 too? Many thanks. #include openssl/pkcs7.h #include openssl/bio.h #include openssl/err.h #include openssl/x509.h void parse(char *pszFileName) { // Parsing PKCS#7 file BIO *foo = BIO_new_file(pszFileName, rb); PKCS7* pP7 = d2i_PKCS7_bio(foo,NULL); STACK_OF(X509) *pSigners = PKCS7_get0_signers(pP7, NULL, 0); STACK_OF(PKCS7_SIGNER_INFO) *pSignerInfos = PKCS7_get_signer_info(pP7); // Looping through the signatures for (int i = 0; i sk_PKCS7_SIGNER_INFO_num(pSignerInfos); i++) { PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(pSignerInfos, i); X509* pSignerCert = sk_X509_value(pSigners, i); printf (FOUND SIGNATURE : %p\n, si); // Parsing counter signatures ASN1_TYPE *pCounterSignatureAttribute = PKCS7_get_attribute(si, NID_pkcs9_countersignature); ASN1_STRING *pSequence = pCounterSignatureAttribute-value.sequence; if (pSequence != NULL) { unsigned char *ps = NULL; ps = pSequence-data; PKCS7_SIGNER_INFO *cs = d2i_PKCS7_SIGNER_INFO(NULL, (const unsigned char**)ps, pSequence-length); printf (FOUND COUNTER SIGNATURE: %p\n, si); } } } Regards, Massimiliano Ziccardi test.txt.p7m Description: S/MIME encrypted message
Re: Parsing counter signatures - HELP - (UPDATED)
Sorry, I've received an error about the attachment, so I'm not sure you've got the e-mail. Follows the original e-mail. At the end, I've also included the PEM encoding of the P7M I tried to send you before (it was DER encoded). Regards, Massimiliano Ziccardi On Tue, May 20, 2008 at 9:25 AM, Massimiliano Ziccardi [EMAIL PROTECTED] wrote: Hi all. I've been able to parse the first counter signature of each signature. At the end of this e-mail, you'll find the code I use to parse the file (no error handling, it's just a working snippet). Attached you'll find my test P7M. The signature/countersignature tree is as follows: SIGNATURE 1 COUNTER SIGNATURE 1 COUNTER SIGNATURE 2 SIGNATURE 2 COUNTER SIGNATURE 1 Can someone please give me an advice about the changes I've to make to the following code to parse the COUNTER SIGNATURE 2 too? Many thanks. #include openssl/pkcs7.h #include openssl/bio.h #include openssl/err.h #include openssl/x509.h void parse(char *pszFileName) { // Parsing PKCS#7 file BIO *foo = BIO_new_file(pszFileName, rb); PKCS7* pP7 = d2i_PKCS7_bio(foo,NULL); STACK_OF(X509) *pSigners = PKCS7_get0_signers(pP7, NULL, 0); STACK_OF(PKCS7_SIGNER_INFO) *pSignerInfos = PKCS7_get_signer_info(pP7); // Looping through the signatures for (int i = 0; i sk_PKCS7_SIGNER_INFO_num(pSignerInfos); i++) { PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(pSignerInfos, i); X509* pSignerCert = sk_X509_value(pSigners, i); printf (FOUND SIGNATURE : %p\n, si); // Parsing counter signatures ASN1_TYPE *pCounterSignatureAttribute = PKCS7_get_attribute(si, NID_pkcs9_countersignature); ASN1_STRING *pSequence = pCounterSignatureAttribute-value.sequence; if (pSequence != NULL) { unsigned char *ps = NULL; ps = pSequence-data; PKCS7_SIGNER_INFO *cs = d2i_PKCS7_SIGNER_INFO(NULL, (const unsigned char**)ps, pSequence-length); printf (FOUND COUNTER SIGNATURE: %p\n, si); } } } Regards, Massimiliano Ziccardi Here is the PEM ENCODED P7M file -BEGIN PKCS7- MIIf8AYJKoZIhvcNAQcCoIIf4TCCH90CAQExCzAJBgUrDgMCGgUAMCQGCSqGSIb3 DQEHAaAXBBVEb2N1bWVudG8gZGkgcHJvdmEuDQqgghmTMIIE+TCCA+GgAwIBAgIE Q51TGTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4u VGUuUy5BLiBTLnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0 aW9uIEF1dGhvcml0eTAeFw0wNzAxMTcxNDAxMDFaFw0wODAxMTcxNDAxMDFaMIIB HjELMAkGA1UEBhMCSVQxVzBVBgNVBAoMTklOLlRFLlMuQS4gLSBJbml6aWF0aXZl IFRlbGVtYXRpY2hlIHBlciBTZXJ2aXppIEFwcGxpY2F0aXZpIFMucC5BLi8wNTI2 Mjg5MDAxNDEPMA0GA1UEBwwGTUlMQU5PMREwDwYDVQQLDAhERUxJVkVSWTEfMB0G A1UECwwWRUJJIFNPTFVUSU9OICYgU1VQUE9SVDEaMBgGA1UEAwwRUk9CRVJUIEJF VFRBw6dTQ0kxEzARBgNVBAQMCkJFVFRBw6dTQ0kxDzANBgNVBCoMBlJPQkVSVDEc MBoGA1UEBRMTSVQ6VFJQRlJVNzZBMDNaMTE0TTERMA8GA1UELhMIMDAwMDI2Njcw gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM3kx9UFiChtOXe1kCHOqxJiZ1Wh s9zzMfMowRuYGFkx22hmasSKivNolrWlfF6IzqeZ98UicUM/GYMaV2ngFJ9hAbKH 8JgiphmNzKuN2rQzzvxrjCzxxkb6ayLzntaZjTF7+/Wi6FiWNO+TgJdpfIvq9l8J emQynyjGdxPZzfRXAgMBAAGjggGFMIIBgTAbBgNVHREEFDASgRB1ZmZfcmFAaW50 ZXNhLml0MC8GCCsGAQUFBwEDBCMwITAIBgYEAI5GAQEwCwYGBACORgEDAgEUMAgG BgQAjkYBBDA/BgNVHSAEODA2MDQGBytMFQEBARQwKTAnBggrBgEFBQcCARYbaHR0 cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0MA4GA1UdDwEB/wQEAwIGQDCBgwYDVR0j BHwweoAUGQkDltG4xVgbfhDkbsT2oBIJEKihXKRaMFgxCzAJBgNVBAYTAklUMRow GAYDVQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAt IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ80QETMDsGA1UdHwQ0MDIwMKAuoCyG Kmh0dHA6Ly9lLXRydXN0Y29tLmludGVzYS5pdC9DUkwvSU5URVNBLmNybDAdBgNV HQ4EFgQUXG6de+FvzxE04M9RAkvmkTqxI+MwDQYJKoZIhvcNAQEFBQADggEBAABg H2zAAuQeEqfIimzEdDlvfmx2b0lE5q/3JQwhiGjuoJXyyyZ/gg14t9Yqlox+lYIe WJR6vlVRFSBsqW/3rADTzFday3Mfe0LLA3Tm2sAqJXEge4Kl6iMI9qT7Fdr4xBNz iUvyCx5WH12aht7oWubYtFZi9Qo8HEM1ECtV4yW3oi825JoaCcSWscOt7j+wqCgp K+qCuZUYAUB1vUcbdh+We+Dps2bfglGJA+uglDT5MiLEcI8k/pzVRPNsy+305aKr 9cZ42l45sm+k7G0BXO1rmEF3XYNqEiqXCvKGE0oqFoXClia4XlmY/0eICie4M6ve gkYRNjq17c1qh82qz44wggVKMIIEMqADAgECAgRGkjFRMA0GCSqGSIb3DQEBBQUA MF4xCzAJBgNVBAYTAml0MSAwHgYDVQQKExdCYW5jYSBkJ0l0YWxpYSBDb2xsYXVk bzEtMCsGA1UECxMkU2Vydml6aSBkaSBjZXJ0aWZpY2F6aW9uZSAtIENvbGxhdWRv MB4XDTA3MDkyNzEwMjgxOVoXDTEwMDkyNzEwNTgxOVowgYYxCzAJBgNVBAYTAmRl MRUwEwYDVQQKEwxub24gcHJlc2VudGUxYDAKBgNVBC4TAzMzMzANBgNVBCoTBlNB TkRSQTAPBgNVBAQTCFNURUhMSU5HMBYGA1UEAxMPU1RFSExJTkcgU0FORFJBMBoG A1UEBRMTREU6U1RIU0RSODFCNDlaMTEySzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw gYkCgYEAs1JENYmcDylCESe0x3QnWjhwfjw5xXbJUb+kE/2pTicFEBxBmBJ2J9Cj zC26L7XSWwFW9n+cjT7xoh1b5s8wvKAWx5VL5lwUGPm58G7yTr04wXSZ/4+NaXgX 9QDkWbwEZQqMMtAoZt1qP3Gubx8rljhvE2CrmUbhJOy+knyMjJkCAwEAAaOCAmkw ggJlMA4GA1UdDwEB/wQEAwIGQDArBgNVHRAEJDAigA8yMDA3MDkyNzEwMjgxOVqB DzIwMTAwOTI3MTA1ODE5WjAvBggrBgEFBQcBAwQjMCEwCAYGBACORgEBMAsGBgQA jkYBAwIBCjAIBgYEAI5GAQQwQQYDVR0gBDowODA2BgsrBgEEAetCAgACATAnMCUG CCsGAQUFBwIBFhlodHRwOi8vY2EuYmFuY2FkaXRhbGlhLml0MIIBcAYDVR0fBIIB
Re: Parsing counter signatures - HELP - (UPDATED)
I'm sure OpenSSL is able to parse more than one counter signature per signature. Can pleas some OpenSSL expert tell me how to do it? I think the code I sent in the previous e-mail should be close to the solution. I just need to know how to get the other counter signatures (I already did in Java with Bouncycastle, and it has been straightforward). I've searched through the net for some documentation, but, as stated on the site, the OpenSSL documentation is very incomplete, and I couldn't find any useful information. Many thanks for your help. Massimiliano Ziccardi On Tue, May 20, 2008 at 9:37 AM, Massimiliano Ziccardi [EMAIL PROTECTED] wrote: Sorry, I've received an error about the attachment, so I'm not sure you've got the e-mail. Follows the original e-mail. At the end, I've also included the PEM encoding of the P7M I tried to send you before (it was DER encoded). Regards, Massimiliano Ziccardi On Tue, May 20, 2008 at 9:25 AM, Massimiliano Ziccardi [EMAIL PROTECTED] wrote: Hi all. I've been able to parse the first counter signature of each signature. At the end of this e-mail, you'll find the code I use to parse the file (no error handling, it's just a working snippet). Attached you'll find my test P7M. The signature/countersignature tree is as follows: SIGNATURE 1 COUNTER SIGNATURE 1 COUNTER SIGNATURE 2 SIGNATURE 2 COUNTER SIGNATURE 1 Can someone please give me an advice about the changes I've to make to the following code to parse the COUNTER SIGNATURE 2 too? Many thanks. #include openssl/pkcs7.h #include openssl/bio.h #include openssl/err.h #include openssl/x509.h void parse(char *pszFileName) { // Parsing PKCS#7 file BIO *foo = BIO_new_file(pszFileName, rb); PKCS7* pP7 = d2i_PKCS7_bio(foo,NULL); STACK_OF(X509) *pSigners = PKCS7_get0_signers(pP7, NULL, 0); STACK_OF(PKCS7_SIGNER_INFO) *pSignerInfos = PKCS7_get_signer_info(pP7); // Looping through the signatures for (int i = 0; i sk_PKCS7_SIGNER_INFO_num(pSignerInfos); i++) { PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(pSignerInfos, i); X509* pSignerCert = sk_X509_value(pSigners, i); printf (FOUND SIGNATURE : %p\n, si); // Parsing counter signatures ASN1_TYPE *pCounterSignatureAttribute = PKCS7_get_attribute(si, NID_pkcs9_countersignature); ASN1_STRING *pSequence = pCounterSignatureAttribute-value.sequence; if (pSequence != NULL) { unsigned char *ps = NULL; ps = pSequence-data; PKCS7_SIGNER_INFO *cs = d2i_PKCS7_SIGNER_INFO(NULL, (const unsigned char**)ps, pSequence-length); printf (FOUND COUNTER SIGNATURE: %p\n, si); } } } Regards, Massimiliano Ziccardi Here is the PEM ENCODED P7M file -BEGIN PKCS7- MIIf8AYJKoZIhvcNAQcCoIIf4TCCH90CAQExCzAJBgUrDgMCGgUAMCQGCSqGSIb3 DQEHAaAXBBVEb2N1bWVudG8gZGkgcHJvdmEuDQqgghmTMIIE+TCCA+GgAwIBAgIE Q51TGTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJJVDEaMBgGA1UEChMRSW4u VGUuUy5BLiBTLnAuQS4xLTArBgNVBAMTJEluLlRlLlMuQS4gLSBDZXJ0aWZpY2F0 aW9uIEF1dGhvcml0eTAeFw0wNzAxMTcxNDAxMDFaFw0wODAxMTcxNDAxMDFaMIIB HjELMAkGA1UEBhMCSVQxVzBVBgNVBAoMTklOLlRFLlMuQS4gLSBJbml6aWF0aXZl IFRlbGVtYXRpY2hlIHBlciBTZXJ2aXppIEFwcGxpY2F0aXZpIFMucC5BLi8wNTI2 Mjg5MDAxNDEPMA0GA1UEBwwGTUlMQU5PMREwDwYDVQQLDAhERUxJVkVSWTEfMB0G A1UECwwWRUJJIFNPTFVUSU9OICYgU1VQUE9SVDEaMBgGA1UEAwwRUk9CRVJUIEJF VFRBw6dTQ0kxEzARBgNVBAQMCkJFVFRBw6dTQ0kxDzANBgNVBCoMBlJPQkVSVDEc MBoGA1UEBRMTSVQ6VFJQRlJVNzZBMDNaMTE0TTERMA8GA1UELhMIMDAwMDI2Njcw gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM3kx9UFiChtOXe1kCHOqxJiZ1Wh s9zzMfMowRuYGFkx22hmasSKivNolrWlfF6IzqeZ98UicUM/GYMaV2ngFJ9hAbKH 8JgiphmNzKuN2rQzzvxrjCzxxkb6ayLzntaZjTF7+/Wi6FiWNO+TgJdpfIvq9l8J emQynyjGdxPZzfRXAgMBAAGjggGFMIIBgTAbBgNVHREEFDASgRB1ZmZfcmFAaW50 ZXNhLml0MC8GCCsGAQUFBwEDBCMwITAIBgYEAI5GAQEwCwYGBACORgEDAgEUMAgG BgQAjkYBBDA/BgNVHSAEODA2MDQGBytMFQEBARQwKTAnBggrBgEFBQcCARYbaHR0 cDovL2UtdHJ1c3Rjb20uaW50ZXNhLml0MA4GA1UdDwEB/wQEAwIGQDCBgwYDVR0j BHwweoAUGQkDltG4xVgbfhDkbsT2oBIJEKihXKRaMFgxCzAJBgNVBAYTAklUMRow GAYDVQQKExFJbi5UZS5TLkEuIFMucC5BLjEtMCsGA1UEAxMkSW4uVGUuUy5BLiAt IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ80QETMDsGA1UdHwQ0MDIwMKAuoCyG Kmh0dHA6Ly9lLXRydXN0Y29tLmludGVzYS5pdC9DUkwvSU5URVNBLmNybDAdBgNV HQ4EFgQUXG6de+FvzxE04M9RAkvmkTqxI+MwDQYJKoZIhvcNAQEFBQADggEBAABg H2zAAuQeEqfIimzEdDlvfmx2b0lE5q/3JQwhiGjuoJXyyyZ/gg14t9Yqlox+lYIe WJR6vlVRFSBsqW/3rADTzFday3Mfe0LLA3Tm2sAqJXEge4Kl6iMI9qT7Fdr4xBNz iUvyCx5WH12aht7oWubYtFZi9Qo8HEM1ECtV4yW3oi825JoaCcSWscOt7j+wqCgp K+qCuZUYAUB1vUcbdh+We+Dps2bfglGJA+uglDT5MiLEcI8k/pzVRPNsy+305aKr 9cZ42l45sm+k7G0BXO1rmEF3XYNqEiqXCvKGE0oqFoXClia4XlmY/0eICie4M6ve gkYRNjq17c1qh82qz44wggVKMIIEMqADAgECAgRGkjFRMA0GCSqGSIb3DQEBBQUA MF4xCzAJBgNVBAYTAml0MSAwHgYDVQQKExdCYW5jYSBkJ0l0YWxpYSBDb2xsYXVk bzEtMCsGA1UECxMkU2Vydml6aSBkaSBjZXJ0aWZpY2F6aW9uZSAtIENvbGxhdWRv MB4XDTA3MDkyNzEwMjgxOVoXDTEwMDkyNzEwNTgxOVowgYYxCzAJBgNVBAYTAmRl
Re: Parsing counter signatures - HELP - (UPDATED)
Massimiliano Ziccardi wrote: I'm sure OpenSSL is able to parse more than one counter signature per signature. Can pleas some OpenSSL expert tell me how to do it? I think the code I sent in the previous e-mail should be close to the solution. I just need to know how to get the other counter signatures (I already did in Java with Bouncycastle, and it has been straightforward). I've searched through the net for some documentation, but, as stated on the site, the OpenSSL documentation is very incomplete, and I couldn't find any useful information. Many thanks for your help. Massimiliano Ziccardi I see that PKCS7_get_attribute() retrieves the first attribute matching the nid. Maybe something like below will do the trick. STACK_OF(X509_ATTRIBUTE) *unauth = PKCS7_get_attributes(si); /* go thru each elem in unauth */ foreach attr in unauth { if(attr-object-nid == NID_pkcs9_countersignature){ /* do something here */ } } On Tue, May 20, 2008 at 9:25 AM, Massimiliano Ziccardi [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote: [snip] #include openssl/pkcs7.h #include openssl/bio.h #include openssl/err.h #include openssl/x509.h void parse(char *pszFileName) { // Parsing PKCS#7 file BIO *foo = BIO_new_file(pszFileName, rb); PKCS7* pP7 = d2i_PKCS7_bio(foo,NULL); STACK_OF(X509) *pSigners = PKCS7_get0_signers(pP7, NULL, 0); STACK_OF(PKCS7_SIGNER_INFO) *pSignerInfos = PKCS7_get_signer_info(pP7); // Looping through the signatures for (int i = 0; i sk_PKCS7_SIGNER_INFO_num(pSignerInfos); i++) { PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(pSignerInfos, i); X509* pSignerCert = sk_X509_value(pSigners, i); printf (FOUND SIGNATURE : %p\n, si); // Parsing counter signatures ASN1_TYPE *pCounterSignatureAttribute = PKCS7_get_attribute(si, NID_pkcs9_countersignature); ASN1_STRING *pSequence = pCounterSignatureAttribute-value.sequence; if (pSequence != NULL) { unsigned char *ps = NULL; ps = pSequence-data; PKCS7_SIGNER_INFO *cs = d2i_PKCS7_SIGNER_INFO(NULL, (const unsigned char**)ps, pSequence-length); printf (FOUND COUNTER SIGNATURE: %p\n, si); } } } Regards, Massimiliano Ziccardi -jb -- Real computer scientists don't comment their code. The identifiers are so long they can't afford the disk space. __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]
Re: Parsing counter signatures - HELP - (UPDATED)
On Tue, May 20, 2008, Massimiliano Ziccardi wrote: I'm sure OpenSSL is able to parse more than one counter signature per signature. Can pleas some OpenSSL expert tell me how to do it? I think the code I sent in the previous e-mail should be close to the solution. I just need to know how to get the other counter signatures (I already did in Java with Bouncycastle, and it has been straightforward). I've searched through the net for some documentation, but, as stated on the site, the OpenSSL documentation is very incomplete, and I couldn't find any useful information. Unfortunately the attribute handling functions are undocumented at present. They opearate in a manner similar to the documented X509_NAME functions though. This is an outline of what you do If you call PKCS7_get_attributes() you will get back a STACK_OF(X509_ATTRIBUTE). Using that you can look through it using the attribute utility functions. int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, int lastpos); You loop round calling X509at_get_attr_by_NID() to retrieve the index of each countersignature attribute, you get -1 when no more can be found. You set lastpos to the last index or -1 initially. For each index you can get the corresponding attribute with: X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); Then for each X509_ATTRIBUTE you can retrieve the count of attributes with X509_ATTRIBUTE_count(). Then each individual using: void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, void *data); You set idx to the index of each one (starting from zero) atrtype to V_ASN1_SEQUENCE and you get back an ASN1_STRING structure or NULL if the type isn't a SEQUENCE: that shouldn't happen unless the countersignature is malformed. The for each string you parse the countersignature as before. Steve. -- Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage OpenSSL project core developer and freelance consultant. Homepage: http://www.drh-consultancy.demon.co.uk __ OpenSSL Project http://www.openssl.org User Support Mailing Listopenssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]