{"id":1621,"date":"2016-03-03T22:38:16","date_gmt":"2016-03-03T20:38:16","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=1621"},"modified":"2016-03-03T22:38:16","modified_gmt":"2016-03-03T20:38:16","slug":"certificate-enrollment-api-adventures","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/1621","title":{"rendered":"Certificate Enrollment API Adventures"},"content":{"rendered":"<p><code><a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa379006\">IX509PrivateKey::Export<\/a><\/code> exports key data from COM object, MSDN:<\/p>\n<blockquote><p><code>strExportType<\/code> [in]<\/p>\n<p>A BSTR value that specifies how the private key is exported.<\/p>\n<p>If the key was created by using a CNG KSP (Key Storage Provider), you can specify one of the values allowed by the pszBlobType parameter in the NCryptExportKey function.<\/p>\n<p>If the key was created by using a CryptoAPI CSP (Cryptographic Service Provider), you can specify one of the following values from the Bcrypt.h header file included with Wincrypt.h.<br \/>\n<strong>BCRYPT_<em>PUBLIC_<\/em>KEY_<em>BLOB &#8211; Exports only the public portion of the private key.<br \/>\nBCRYPT_<\/em>PRIVATE_<em>KEY_<\/em>BLOB &#8211; Exports the entire private key.<\/strong><\/p><\/blockquote>\n<p>Well this is actually accurate, however trying to make it&#8230;<\/p>\n<pre><code>CComPtr&lt;IX509PrivateKey&gt; pPrivateKey;\r\n\/\/ ...\r\nCComBSTR sPublicKeyBlob, sPrivateKeyBlob;\r\nATLENSURE_SUCCEEDED(pPrivateKey-&gt;Export(BCRYPT_PUBLIC_KEY_BLOB, XCN_CRYPT_STRING_BASE64, &amp;sPublicKeyBlob));\r\nATLENSURE_SUCCEEDED(pPrivateKey-&gt;Export(BCRYPT_PRIVATE_KEY_BLOB, XCN_CRYPT_STRING_BASE64, &amp;sPrivateKeyBlob));\r\n<\/code><\/pre>\n<p>&#8230; the both calls result in <code>E_POINTER<\/code> (0x80004003). The first argument is not just <code>LPCWSTR<\/code>. It has to be BSTR and the API is checking the length of the value using <code>SysStringLen<\/code>. One has to wrap the argument to provide it as <code>BSTR<\/code>:<\/p>\n<pre><code>CComPtr&lt;IX509PrivateKey&gt; pPrivateKey;\r\n\/\/ ...\r\nCComBSTR sPublicKeyBlob, sPrivateKeyBlob;\r\nATLENSURE_SUCCEEDED(pPrivateKey-&gt;Export(CComBSTR(BCRYPT_PUBLIC_KEY_BLOB), XCN_CRYPT_STRING_BASE64, &amp;sPublicKeyBlob));\r\nATLENSURE_SUCCEEDED(pPrivateKey-&gt;Export(CComBSTR(BCRYPT_PRIVATE_KEY_BLOB), XCN_CRYPT_STRING_BASE64, &amp;sPrivateKeyBlob));\r\n<\/code><\/pre>\n<p>Another problem is related to <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms221240\"><code>IObjectId::InitializeFromAlgorithmName<\/code><\/a>.<\/p>\n<blockquote><p>strAlgorithmName [in]<\/p>\n<p>A BSTR variable that contains the name. <strong>You can specify a name, or an OID in dotted decimal format.<\/strong> The method verifies that the format is consistent with the ASN.1 X.208 standard. For more information about CNG algorithm names, see CNG Algorithm Identifiers.<\/p><\/blockquote>\n<p>MSDN offers choices to provide a string or <code>OID<\/code>. Unfortunately, OID does not work and fails on internal argument validation with <code>E_INVALIDARG<\/code> (0x80070057).<\/p>\n<pre><code>ATLENSURE_SUCCEEDED(pObjectId-&gt;InitializeFromAlgorithmName(XCN_CRYPT_HASH_ALG_OID_GROUP_ID, \r\n    XCN_CRYPT_OID_INFO_PUBKEY_ANY, AlgorithmFlagsNone, \r\n        CComBSTR(L\"SHA256\"))); \/\/CComBSTR(szOID_RSA_SHA256RSA)));\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>IX509PrivateKey::Export exports key data from COM object, MSDN: strExportType [in] A BSTR value that specifies how the private key is exported. If the key was created by using a CNG KSP (Key Storage Provider), you can specify one of the values allowed by the pszBlobType parameter in the NCryptExportKey function. If the key was created&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/1621\">Read the full article<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[329,509,70,510],"class_list":["post-1621","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-msdn","tag-pkcs","tag-winapi","tag-x-509"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1621","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=1621"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/1621\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=1621"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=1621"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=1621"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}