/***************************************************************************** * HrCreateKey * * This function uses the NCrypt API to open the storage provider * and create the key *****************************************************************************/ static HRESULT HrCreateKey(string pwszProvName, string wszContainerName, string pwszAlgid, uint dwBits, out SafeNCRYPT_KEY_HANDLE phKey) { SafeNCRYPT_PROV_HANDLE hProvider = default; HRESULT hr = HRESULT.S_OK; phKey = default; hr = NCryptOpenStorageProvider(out hProvider, pwszProvName ?? KnownStorageProvider.MS_KEY_STORAGE_PROVIDER); if (hr.Failed) { goto CleanUp; } hr = NCryptOpenKey(hProvider, out phKey, wszContainerName); if (hr.Succeeded) { hr = NCryptDeleteKey(phKey); phKey.Dispose(); phKey = default; if (hr.Failed) { goto CleanUp; } } hr = NCryptCreatePersistedKey(hProvider, out phKey, pwszAlgid, wszContainerName); if (hr.Failed) { goto CleanUp; } if (0 != dwBits) { using var pdwBits = new PinnedObject(dwBits); hr = NCryptSetProperty(phKey, NCrypt.PropertyName.NCRYPT_LENGTH_PROPERTY, pdwBits, (uint)Marshal.SizeOf(dwBits), SetPropFlags.NCRYPT_PERSIST_FLAG); if (hr.Failed) { goto CleanUp; } } hr = NCryptFinalizeKey(phKey); if (hr.Failed) { goto CleanUp; } hr = HRESULT.S_OK; CleanUp: if (hr.Failed) { phKey?.Dispose(); phKey = null; } hProvider?.Dispose(); return(hr); }
/***************************************************************************** * wmain * *****************************************************************************/ static int Main(string[] args) { HRESULT hr = HRESULT.S_OK; SafeHCERTSTORE hStoreHandle = default; string wszStoreName = "MY"; // by default, MY string wszContainerName = "SAMPLE"; uint dwBits = 0; string wszKeyAlgName = "RSA"; // string[] rgwszCNGAlgs = new string[] { "SHA1", "RSA" }; SafeNCRYPT_KEY_HANDLE hCNGKey = default; SafePCCERT_CONTEXT pCertContext = default; CRYPTOAPI_BLOB SubjectName = default; int i; // // options // for (i = 0; i < args.Length; i++) { if (string.Compare(args[i], "/?") == 0 || string.Compare(args[i], "-?") == 0) { Usage("CreateCert.exe"); goto CleanUp; } if (args[i][0] != '-') { break; } if (string.Compare(args[i], "-s") == 0) { if (i + 1 >= args.Length) { hr = HRESULT.E_INVALIDARG; goto CleanUp; } wszStoreName = args[++i]; } else if (string.Compare(args[i], "-c") == 0) { if (i + 1 >= args.Length) { hr = HRESULT.E_INVALIDARG; goto CleanUp; } wszContainerName = args[++i]; } else if (string.Compare(args[i], "-k") == 0) { if (i + 1 >= args.Length) { hr = HRESULT.E_INVALIDARG; goto CleanUp; } wszKeyAlgName = args[++i]; } else if (string.Compare(args[i], "-h") == 0) { if (i + 1 >= args.Length) { hr = HRESULT.E_INVALIDARG; goto CleanUp; } rgwszCNGAlgs[0] = args[++i]; } else if (string.Compare(args[i], "-l") == 0) { if (i + 1 >= args.Length) { hr = HRESULT.E_INVALIDARG; goto CleanUp; } dwBits = uint.Parse(args[++i]); } } if (i >= args.Length) { hr = HRESULT.E_INVALIDARG; goto CleanUp; } var wszSubject = args[i]; // // Find the Signature algorithm // var pOidInfo = CryptFindOIDInfo(CryptOIDInfoFlags.CRYPT_OID_INFO_NAME_KEY, wszKeyAlgName, OIDGroupId.CRYPT_PUBKEY_ALG_OID_GROUP_ID); if (default == pOidInfo) { Console.Write("FAILED: Unable to find Public Key algorithm: '{0}'.\n", wszKeyAlgName); hr = HRESULT.CRYPT_E_UNKNOWN_ALGO; goto CleanUp; } var oidInfo = (CRYPT_OID_INFO)pOidInfo; if (!string.IsNullOrEmpty(oidInfo.pwszCNGExtraAlgid)) { rgwszCNGAlgs[1] = oidInfo.pwszCNGExtraAlgid; } else { rgwszCNGAlgs[1] = oidInfo.pwszCNGAlgid; } using (var pAlgs = SafeLocalHandle.CreateFromStringList(rgwszCNGAlgs, StringListPackMethod.Packed, CharSet.Unicode)) pOidInfo = CryptFindOIDInfo(CryptOIDInfoFlags.CRYPT_OID_INFO_CNG_SIGN_KEY, pAlgs, OIDGroupId.CRYPT_SIGN_ALG_OID_GROUP_ID); if (default == pOidInfo) { Console.Write("FAILED: Unable to find signature algorithm: '{0}:{1}'\n", rgwszCNGAlgs[0], rgwszCNGAlgs[1]); hr = HRESULT.CRYPT_E_UNKNOWN_ALGO; goto CleanUp; } var SignatureAlgorithm = new CRYPT_ALGORITHM_IDENTIFIER { pszObjId = ((CRYPT_OID_INFO)pOidInfo).pszOID }; //------------------------------------------------------------------- // Open a system store, in this case, the My store. hStoreHandle = CertOpenStore(CertStoreProvider.CERT_STORE_PROV_SYSTEM, 0, default, CertStoreFlags.CERT_SYSTEM_STORE_CURRENT_USER, wszStoreName);