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

Popular posts from this blog

how to insert data php javascript mysql with multiple array session 2 -

multithreading - Exception in Application constructor -