1 #include "stdio.h" 2 #include "conio.h" 3 #include "windows.h" 4 #include "wincrypt.h" 5 #include "tchar.h" 6 7 8 #pragma comment(lib, "Crypt32.lib") 9 10 11 int SelfSignedCertificateTest() 12 { 13 // CREATE KEY PAIR FOR SELF-SIGNED CERTIFICATE IN MACHINE PROFILE 14 15 HCRYPTPROV hCryptProv = NULL; 16 HCRYPTKEY hKey = NULL; 17 18 __try 19 { 20 // Acquire key container 21 _tprintf(_T("CryptAcquireContext... ")); 22 if (!CryptAcquireContext(&hCryptProv, _T("alejacma"), NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) 23 { 24 // Error 25 _tprintf(_T("Error 0x%x "), GetLastError()); 26 27 // Try to create a new key container 28 _tprintf(_T("CryptAcquireContext... ")); 29 if (!CryptAcquireContext(&hCryptProv, _T("alejacma"), NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET)) 30 { 31 // Error 32 _tprintf(_T("Error 0x%x "), GetLastError()); 33 return 0; 34 } 35 else 36 { 37 _tprintf(_T("Success ")); 38 } 39 } 40 else 41 { 42 _tprintf(_T("Success ")); 43 } 44 45 // Generate new key pair 46 _tprintf(_T("CryptGenKey... ")); 47 if (!CryptGenKey(hCryptProv, AT_SIGNATURE, 0x08000000 /*RSA-2048-BIT_KEY*/, &hKey)) 48 { 49 // Error 50 _tprintf(_T("Error 0x%x "), GetLastError()); 51 return 0; 52 } 53 else 54 { 55 _tprintf(_T("Success ")); 56 } 57 } 58 __finally 59 { 60 // Clean up 61 62 if (hKey) 63 { 64 _tprintf(_T("CryptDestroyKey... ")); 65 CryptDestroyKey(hKey); 66 _tprintf(_T("Success ")); 67 } 68 if (hCryptProv) 69 { 70 _tprintf(_T("CryptReleaseContext... ")); 71 CryptReleaseContext(hCryptProv, 0); 72 _tprintf(_T("Success ")); 73 } 74 } 75 76 // CREATE SELF-SIGNED CERTIFICATE AND ADD IT TO ROOT STORE IN MACHINE PROFILE 77 78 PCCERT_CONTEXT pCertContext = NULL; 79 BYTE *pbEncoded = NULL; 80 HCERTSTORE hStore = NULL; 81 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey = NULL; 82 BOOL fCallerFreeProvOrNCryptKey = FALSE; 83 84 __try 85 { 86 // Encode certificate Subject 87 LPCTSTR pszX500 = _T("CN=Alejacma, T=Test"); 88 DWORD cbEncoded = 0; 89 _tprintf(_T("CertStrToName... ")); 90 if (!CertStrToName(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, NULL, pbEncoded, &cbEncoded, NULL)) 91 { 92 // Error 93 _tprintf(_T("Error 0x%x "), GetLastError()); 94 return 0; 95 } 96 else 97 { 98 _tprintf(_T("Success ")); 99 } 100 101 _tprintf(_T("malloc... ")); 102 if (!(pbEncoded = (BYTE *)malloc(cbEncoded))) 103 { 104 // Error 105 _tprintf(_T("Error 0x%x "), GetLastError()); 106 return 0; 107 } 108 else 109 { 110 _tprintf(_T("Success ")); 111 } 112 113 _tprintf(_T("CertStrToName... ")); 114 if (!CertStrToName(X509_ASN_ENCODING, pszX500, CERT_X500_NAME_STR, NULL, pbEncoded, &cbEncoded, NULL)) 115 { 116 // Error 117 _tprintf(_T("Error 0x%x "), GetLastError()); 118 return 0; 119 } 120 else 121 { 122 _tprintf(_T("Success ")); 123 } 124 125 // Prepare certificate Subject for self-signed certificate 126 CERT_NAME_BLOB SubjectIssuerBlob; 127 memset(&SubjectIssuerBlob, 0, sizeof(SubjectIssuerBlob)); 128 SubjectIssuerBlob.cbData = cbEncoded; 129 SubjectIssuerBlob.pbData = pbEncoded; 130 131 // Prepare key provider structure for self-signed certificate 132 CRYPT_KEY_PROV_INFO KeyProvInfo; 133 memset(&KeyProvInfo, 0, sizeof(KeyProvInfo)); 134 const TCHAR* name = _T("alejacma"); 135 KeyProvInfo.pwszContainerName = (LPTSTR)name; 136 KeyProvInfo.pwszProvName = NULL; 137 KeyProvInfo.dwProvType = PROV_RSA_FULL; 138 KeyProvInfo.dwFlags = CRYPT_MACHINE_KEYSET; 139 KeyProvInfo.cProvParam = 0; 140 KeyProvInfo.rgProvParam = NULL; 141 KeyProvInfo.dwKeySpec = AT_SIGNATURE; 142 143 // Prepare algorithm structure for self-signed certificate 144 CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm; 145 memset(&SignatureAlgorithm, 0, sizeof(SignatureAlgorithm)); 146 SignatureAlgorithm.pszObjId = (LPSTR)szOID_RSA_SHA1RSA; 147 148 // Prepare Expiration date for self-signed certificate 149 SYSTEMTIME EndTime; 150 GetSystemTime(&EndTime); 151 EndTime.wYear += 5; 152 153 // Create self-signed certificate 154 _tprintf(_T("CertCreateSelfSignCertificate... ")); 155 pCertContext = CertCreateSelfSignCertificate(NULL, &SubjectIssuerBlob, 0, &KeyProvInfo, &SignatureAlgorithm, 0, &EndTime, 0); 156 if (!pCertContext) 157 { 158 // Error 159 _tprintf(_T("Error 0x%x "), GetLastError()); 160 return 0; 161 } 162 else 163 { 164 _tprintf(_T("Success ")); 165 } 166 167 // Open Root cert store in machine profile 168 _tprintf(_T("CertOpenStore... ")); 169 hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0 170 , CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY"); 171 if (!hStore) 172 { 173 // Error 174 _tprintf(_T("Error 0x%x "), GetLastError()); 175 return 0; 176 } 177 else 178 { 179 _tprintf(_T("Success ")); 180 } 181 182 // Add self-signed cert to the store 183 _tprintf(_T("CertAddCertificateContextToStore... ")); 184 if (!CertAddCertificateContextToStore(hStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, 0)) 185 { 186 // Error 187 _tprintf(_T("Error 0x%x "), GetLastError()); 188 return 0; 189 } 190 else 191 { 192 _tprintf(_T("Success ")); 193 } 194 195 // Just for testing, verify that we can access self-signed cert's private key 196 DWORD dwKeySpec; 197 _tprintf(_T("CryptAcquireCertificatePrivateKey... ")); 198 if (!CryptAcquireCertificatePrivateKey(pCertContext, 0, NULL, &hCryptProvOrNCryptKey, &dwKeySpec, &fCallerFreeProvOrNCryptKey)) 199 { 200 // Error 201 _tprintf(_T("Error 0x%x "), GetLastError()); 202 return 0; 203 } 204 else 205 { 206 _tprintf(_T("Success ")); 207 } 208 } 209 __finally 210 { 211 // Clean up 212 213 if (!pbEncoded) { 214 _tprintf(_T("free... ")); 215 free(pbEncoded); 216 _tprintf(_T("Success ")); 217 } 218 219 if (hCryptProvOrNCryptKey) 220 { 221 _tprintf(_T("CryptReleaseContext... ")); 222 CryptReleaseContext(hCryptProvOrNCryptKey, 0); 223 _tprintf(_T("Success ")); 224 } 225 226 if (pCertContext) 227 { 228 _tprintf(_T("CertFreeCertificateContext... ")); 229 CertFreeCertificateContext(pCertContext); 230 _tprintf(_T("Success ")); 231 } 232 233 if (hStore) 234 { 235 _tprintf(_T("CertCloseStore... ")); 236 CertCloseStore(hStore, 0); 237 _tprintf(_T("Success ")); 238 } 239 } 240 } 241 242 int _tmain(int argc, _TCHAR* argv[]) 243 { 244 SelfSignedCertificateTest(); 245 246 _tprintf(_T("<< Press any key>> ")); 247 _getch(); 248 return 0; 249 }