windows - CertCreateCertificateContext returns CRYPT_E_ASN1_BADTAG / 8009310b -
i realize similar post others (e.g. this one), there details missing posts might significant case.
to start with, here's simplified program:
#include "stdafx.h" #include <windows.h> #include <wincrypt.h> int _tmain(int argc, _tchar* argv[]) { // usage: certextract certpath char keyfile[] = "c:\\certificates\\public.crt"; byte lp[65536]; security_attributes sa; handle hkeyfile; dword bytes; pccert_context certcontext; sa.nlength = sizeof(sa); sa.lpsecuritydescriptor = null; sa.binherithandle = false; hkeyfile = createfile(keyfile, generic_read, file_share_read, &sa, open_existing, file_attribute_normal, null); if (hkeyfile) { if (readfile(hkeyfile, lp, getfilesize(hkeyfile, null), &bytes, null) && bytes > 0) { certcontext = certcreatecertificatecontext(x509_asn_encoding, lp, bytes); if (certcontext) { printf("yay!"); certfreecertificatecontext(certcontext); } else { printf("could not convert certificate internal form\n"); } } else { printf("failed read key file: %s\n", keyfile); } } else { printf("failed open key file: %s\n", keyfile); } closehandle(hkeyfile); return 0; } in order create certificate, used following steps openssl:
c:\certificates>openssl genrsa -out private.key 1024 loading 'screen' random state - done generating rsa private key, 1024 bit long modulus ......................................++++++ ................++++++ e 65537 (0x10001) c:\certificates>openssl req -new -key private.key -out public.csr loading 'screen' random state - done c:\certificates>copy private.key private.key.org 1 file(s) copied. c:\certificates>openssl rsa -in private.key.org -out private.key writing rsa key c:\certificates>openssl x509 -req -days 365 -in public.csr -signkey private.key -ou t public.crt loading 'screen' random state - done signature ok subject=/cn=my signing cert getting private key with following conf file:
randfile = .rnd [ req ] distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] commonname = signing cert the certificate file looks like:
-----begin certificate----- miibqzccarqccqdujywk0oxlrtanbgkqhkig9w0baqufadaamrgwfgydvqqdda9n esbtawduaw5nienlcnqwhhcnmtywmta1mjizodu5whcnmtcwmta0mjizodu5wjaa mrgwfgydvqqdda9nesbtawduaw5nienlcnqwgz8wdqyjkozihvcnaqebbqadgy0a migjaogbajobihfssmlepeg9sobelwho4hjkxe8dt6cllpr6qxdxe2vnlh9fxvlx spvgfqwjlf3ohynmsqny3m2b5wlfnyvuhvy8ruszwof4drsbiqwkh0tuj+4mbegq eormtj+kigqnm5ivrrtu9ov8f0xqtgv1pxhircqxsghxy5w0qtjjagmbaaewdqyj kozihvcnaqefbqadgyeaedqjkfmyifc8nubj6t/y8d+fjfwccdwojufizr78fewa izsas1b1bxska+qeoow7pydbafznud3wfzaizpqflr4rpniqhzya0oiddpwzqqla 3zpkqjj6qetwei5/arzo+stvv4m3og3gqjmchb8h/gxswdbcompvp82dtuet+zu= -----end certificate----- converting pem-encoding hex allows me identify parts of certificate:
30 sequence //certificate (82 01 ab) 30 sequence //tbscertificate (82 01 14) 02 integer //serialnumber (09) 00 d4 27 25 a4 d0 ec 65 45 30 sequence //signature (0d) 06 object identifier (09) 2a 86 48 86 f7 0d 01 01 05 05 null (00) 30 sequence //issuer (1a) 31 set (18) 30 sequence (16) 06 object identifier (03) 55 04 03 0c utf8string (0f) 4d 79 20 53 69 67 6e 69 6e 67 20 43 65 72 74 30 sequence //validity (1e) 17 utctime (0d) 31 36 30 31 30 35 32 32 33 38 35 39 5a 17 utctime (0d) 31 37 30 31 30 34 32 32 33 38 35 39 5a 30 sequence //subjectname (1a) 31 set (18) 30 sequence (16) 06 object identifier (03) 55 04 03 0c utf8string (0f) 4d 79 20 53 69 67 6e 69 6e 67 20 43 65 72 74 30 sequence //subjectpublickeyinfo (81 9f) 30 sequence //algorithmid (0d) 06 object identifier //algorithm (09) 2a 86 48 86 f7 0d 01 01 01 05 null (00) 03 bit string //subjectpublickey (81 8d) [00] //padding bits 30 sequence //rsapublickey (81 89) 02 integer //modulus (81 81) 00 9a 1b 22 17 d2 48 c2 c4 3d e1 bd 48 e0 5e 95 61 e8 e2 18 ca 5d ef 1d 4f a7 25 94 fa fa 41 77 57 7b 65 4d 2e 1f 5f c5 59 71 b2 95 46 15 0c 23 94 5d ce 1d 89 e6 49 09 d8 de 6d 9b e7 09 45 35 85 6e 1e fc bc ad 4b 19 58 e1 78 76 b4 9b 8a a5 8a 87 44 ee 27 ee 0c 05 e1 aa 12 8a e6 4c 9f a4 88 6a 8d 9b 92 15 46 b4 ee f4 e5 7c 7f 45 d0 4c 65 75 a7 11 e2 ad c4 31 b0 68 71 63 9c 34 41 38 e3 02 03 01 00 01 30 sequence //signaturealgorithm (0d) 06 object identifier (09) 2a 86 48 86 f7 0d 01 01 05 05 null (00) 03 bit string //signaturevalue (81 81) [00] //padding bits 79 da a3 29 f3 32 20 50 bc 9d 46 c9 ea df d8 f0 3f 9f 24 5c 02 71 dc 28 8d 41 62 ce fc 14 4c 00 21 94 9a b3 56 f5 6d 74 a4 03 e4 04 a2 85 bb a5 87 41 01 fc cd b8 3d d6 7d 90 08 66 9a 85 96 2b 3c d2 2a 1f 36 1a d0 e2 1d 0c fc 33 41 02 da df 33 ca aa 38 fa 41 e4 d6 12 2e 7f 02 bc ce fa c4 d5 bf 89 b7 3a 0d c6 42 33 02 85 bf 07 fc 6c 6c 59 d6 c2 a2 63 d5 3f cd 83 4d 47 ad f9 95 which appears conform x.509 specs (as expect to):
certificate ::= { tbscertificate tbscertificate, signaturealgorithm algorithmidentifier, signaturevalue bit string } tbscertificate ::= sequence { version [0] version default v1, <-- mean? serialnumber integer, signature algorithmidentifier, issuer name, validity validity, subjectname name, subjectpublickeyinfo subjectpublickeyinfo ... } with lone exception of version part, isn't clear me whether optional or not (though never seems added certificates create openssl).
i can open certificate import certificate store (and can import store), don't think wrong file/encoding.
when reach call certcreatecertificatecontext, lp buffer looks like:
-----begin certificate-----\nmiibqzccarqccqdujywk0oxlrtanbgkqhkig9w0baqufadaamrgwfgydvqqdda9n\nesbtawduaw5nienlcnqwhhcnmtywmta1mjizodu5whcnmtcwmta0mjizodu5wjaa\nmrgwfgydvqqdda9nesbtawduaw5nienlcnqwgz8wdq... and bytes = 639 -- file size.
i've tried adding logic strip out certificate comments, examples of importing certificate in manner don't indicate should necessary.
i've tried setting dwcertencodingtype x509_asn_encoding | pkcs_7_asn_encoding , pkcs_7_asn_encoding out of desperation (though don't believe using pkcs#7 encoding here...a little fuzzy on that).
does have suggestions on might doing incorrectly here? appreciate it.
i figured out issue. certcreatecertificatecontext expecting binary asn.1 data, not pem-encoded certificate created openssl. figured out using microsoft certificate generation tool , testing certificate out:
c:\program files\microsoft sdks\windows\v7.1\bin>makecert.exe -n "cn=test signing cert" -b 0 1/06/2016 -e 01/06/2017 -len 1024 -r c:\certificates\public_v2.crt succeeded looking @ file in hex editor, looked precisely asn.1 binary data. next, used copy file feature certificate viewer launches when double-click certificate copy original public.crt file der encoded binary x.509 (.cer) file , verified program began work (that is, certcreatecertificatecontext happy).
so, in case else bumping against same issue having, here complete solution importing pem-encoded certificate file memory use crypto api:
#include "stdafx.h" #include <windows.h> #include <wincrypt.h> #define lf 0x0a int _tmain(int argc, _tchar* argv[]) { char keyfile[] = "c:\\certificates\\public.crt"; byte lp[65536]; security_attributes sa; handle hkeyfile; dword bytes; pccert_context certcontext; byte *p; dword flags; sa.nlength = sizeof(sa); sa.lpsecuritydescriptor = null; sa.binherithandle = false; hkeyfile = createfile(keyfile, generic_read, file_share_read, &sa, open_existing, file_attribute_normal, null); if (hkeyfile) { if (readfile(hkeyfile, lp, getfilesize(hkeyfile, null), &bytes, null) && bytes > 0) { p = lp + bytes; if (cryptstringtobinary((char *)lp, p - lp, crypt_string_base64_any, p, &bytes, null, &flags) && bytes > 0) { certcontext = certcreatecertificatecontext(x509_asn_encoding, p, bytes); if (certcontext) { printf("yay!"); certfreecertificatecontext(certcontext); } else { printf("could not convert certificate internal form\n"); } } else { printf("failed convert pem"); } } else { printf("failed read key file: %s\n", keyfile); } } else { printf("failed open key file: %s\n", keyfile); } closehandle(hkeyfile); return 0; } note:
because i'm lazy, decode pem encoding binary in same byte array used load file -- simple test, expedient, if you're looking implement sort of thing real, wouldn't recommend it
Comments
Post a Comment