📄 createcert.c
字号:
//===================================================================
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright 1998 - 2000. Microsoft Corporation. All Right Reserved.
// File: CreateCert.c
//
// This sample demonstrates how to create Certificates using CryptoAPI.
// The sample lets the user create Self-Signed Certificates or
// create Certificates signed by another Certificate.
//
// When a Self-Signed Certificate is created a file called
// SelfSigned.cer is created. The file can be ran to trust
// the certificate as a Certificate Authority.
//
// When a non Self-Signed Certificate is created a file called
// Certificate.cer is created. This can be used on Windows 2000
// to install the certificate under the "AddressBook" store for
// example. Only the public key information is stored in the
// certificate.
//
//===================================================================
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _WIN32_WINNT 0x0400
#include <TAPI.h>
typedef unsigned long * ULONG_PTR ;
#include <wincrypt.h>
#include <windows.h>
#include <rpc.h>
#include <stdio.h>
#include "CreateCert.h"
#define KEY_USAGE_SIZE 5
#define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
// This structure will be used to calculate
// the Enhanced Key Usage Extension from an
// integer
typedef struct tagEnhKeyUsage
{
DWORD dwCount;
LPSTR szUsage[KEY_USAGE_SIZE];
DWORD dwValue[KEY_USAGE_SIZE];
} ENHKEYUSAGE;
// Every Enhanced Usage Extension has a
// corresponding number to it. Just add
// the number to set the appropriate
// extension:
// Server Authentication 1
// Client Authentication 2
// Code Signing 4
// Email Protection 8
// Time Stamping 16
ENHKEYUSAGE g_EnhKeyUsage =
{
KEY_USAGE_SIZE,
{
szOID_PKIX_KP_SERVER_AUTH,
szOID_PKIX_KP_CLIENT_AUTH,
szOID_PKIX_KP_CODE_SIGNING,
szOID_PKIX_KP_EMAIL_PROTECTION,
szOID_PKIX_KP_TIMESTAMP_SIGNING
},
{ 1, 2, 4, 8, 16}
};
LPSTR g_szSigAlg[] = {
szOID_RSA_MD5RSA,
szOID_RSA_SHA1RSA
};
// Default store and empty string
LPSTR g_szMyStore = "MY";
LPSTR g_szEmpty = "";
int main(int argc, char *argv[])
{
BOOL bResult;
DWORD dwUsage = 0;
DWORD dwKeyType = AT_KEYEXCHANGE;
DWORD dwProvNum = 0;
LPSTR szSigAlg = g_szSigAlg[1];
BOOL bExport = FALSE;
BOOL bSelfSigned = TRUE;
BOOL bIssuerUser = TRUE;
BOOL bSubjectUser = TRUE;
BOOL bUseProv = FALSE;
LPSTR szX509 = NULL;
LPSTR szSubjectStore = g_szMyStore;
LPSTR szIssuerStore = g_szMyStore;
LPSTR szIssuerName = g_szEmpty;
LPSTR szCertFile = g_szEmpty;
LPSTR szKeyFile = g_szEmpty;
LPSTR szPassword = g_szEmpty;
WORD wMonths = 0;
BOOL bCA = FALSE;
int n;
// Print Usage
if (argc < 2)
{
PrintUsage();
return 0;
}
// User wants to import a certificate
if (strcmpi(argv[1], "-i") == 0)
{
BOOL bUser;
DWORD num;
if (argc != 8)
{
PrintUsage();
return 0;
}
if (strcmpi(argv[6], "m") == 0)
bUser = FALSE;
else
bUser = TRUE;
num = (DWORD)atoi(argv[7]);
bResult = ImportCertificate(argv[2],
argv[3],
argv[4],
argv[5],
bUser,
num);
if (!bResult)
{
printf("Unable to Import Certificate\n");
return 0;
}
else
{
printf("Certificate Imported successfully\n");
return 1;
}
}
// =================================Set X509 Name
szX509 = argv[1];
// Parse rest of the options
n = 2;
while (n < argc)
{
// User selected Key Type
if (strcmpi(argv[n], "-k") == 0)
{
if ((n+1) < argc)
{
if (strcmpi(argv[++n], "s") == 0)
dwKeyType = AT_SIGNATURE;
else
dwKeyType = AT_KEYEXCHANGE;
}
else
{
PrintUsage();
return 0;
}
}
// User set number of months
if (strcmpi(argv[n], "-m") == 0)
{
if ((n+1) < argc)
{
wMonths = (WORD)atoi(argv[++n]);
}
else
{
PrintUsage();
return 0;
}
}
// User wants this to be a CA. Indicated in
// Basic contraints
if (strcmpi(argv[n], "-ca") == 0)
{
bCA = TRUE;
}
// User wants to set Enhanced Key usage extension
if (strcmpi(argv[n], "-u") == 0)
{
if ((n+1) < argc)
{
dwUsage = (DWORD)atoi(argv[++n]);
}
else
{
PrintUsage();
return 0;
}
}
// User wants to set the Crypto Provider
if (strcmpi(argv[n], "-p") == 0)
{
if ((n+1) < argc)
{
bUseProv = TRUE;
dwProvNum = (DWORD)atoi(argv[++n]);
}
else
{
PrintUsage();
return 0;
}
}
// User selected signature algorithm
if (strcmpi(argv[n], "-s") == 0)
{
if ((n+1) < argc)
{
if (strcmpi(argv[++n], "md5") == 0)
szSigAlg = g_szSigAlg[0];
else
szSigAlg = g_szSigAlg[1];
}
else
{
PrintUsage();
return 0;
}
}
// User selected the Subject Location
if (strcmpi(argv[n], "-sl") == 0)
{
if ((n+2) < argc)
{
bExport = FALSE;
szSubjectStore = argv[++n]; // my
if (strcmpi(argv[++n], "m") == 0) // u
bSubjectUser = FALSE;
else
bSubjectUser = TRUE;
}
else
{
PrintUsage();
return 0;
}
}
// User wants to export the Certificate
if (strcmpi(argv[n], "-ex") == 0)
{
if ((n+3) < argc)
{
bExport = TRUE;
szCertFile = argv[++n];
szKeyFile = argv[++n];
szPassword = argv[++n];
}
else
{
PrintUsage();
return 0;
}
}
// User has selected an issuer
if (strcmpi(argv[n], "-is") == 0)
{
if ((n+3) < argc)
{
bSelfSigned = FALSE;
szIssuerName = argv[++n];
szIssuerStore = argv[++n];
if (strcmpi(argv[++n], "m") == 0)
bIssuerUser = FALSE;
else
bIssuerUser = TRUE;
}
else
{
PrintUsage();
return 0;
}
}
n++;
}
// Create Certificate
bResult = CreateCertificate(
szX509, // Certificate Name
dwKeyType, // Key Type
szSigAlg, // Signature Algorithm
wMonths, // Number of Months
dwUsage, // Enhanced Key Usage
bCA, // CA or not
bUseProv, // Use dwProvNum
dwProvNum, // Provider Number
szSubjectStore,// Certificate Store
bSubjectUser, // User or Machine flag
bSelfSigned, // Self Signed flag
szIssuerName, // Issuer of Certificate
szIssuerStore, // Store of Issuer
bIssuerUser, // User or Machine flag
bExport, // Export flag
szCertFile, // Certificate File
szKeyFile, // Key File
szPassword); // Password for Key File
if (!bResult)
{
printf("Unable to create certificate\n");
}
return 1;
}
//
// ImportCertificate installs the crpto provider and certificate
// on the machine.
//
BOOL ImportCertificate(LPSTR szCertFile, LPSTR szKeyFile, LPSTR szPassword,
LPSTR szStore, BOOL bUser, DWORD dwProviderNum)
{
LPSTR szContainer = NULL;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HCERTSTORE hStore = NULL;
HCRYPTKEY hKey = 0;
HCRYPTKEY hPubKey = 0;
HANDLE hFile = INVALID_HANDLE_VALUE;
LPBYTE pbEncodedCert = NULL;
LPBYTE pbEncodedKey = NULL;
PCCERT_CONTEXT pCertContext = NULL;
CRYPT_KEY_PROV_INFO CertKeyInfo;
BOOL fReturn = FALSE;
RPC_STATUS Status;
HANDLE hHeap;
UUID Uuid;
BOOL bResult;
DWORD dwSize, dwRead;
WCHAR szwStore[20];
DWORD dwAcquireFlags = 0;
DWORD dwCertOpenFlags = CERT_SYSTEM_STORE_CURRENT_USER;
CHAR szProvider[260] = { MS_DEF_PROV };
DWORD dwProviderType = PROV_RSA_FULL;
int i;
__try
{
if (!bUser)
{
dwAcquireFlags = CRYPT_MACHINE_KEYSET;
dwCertOpenFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE;
}
dwSize = 260;
bResult = MyCryptEnumProviders(dwProviderNum,
NULL,
0,
&dwProviderType,
szProvider,
&dwSize);
if (!bResult)
{
printf("Unable to get provider\n");
__leave;
}
// Get process heap
hHeap = GetProcessHeap();
// Open Key File
hFile = CreateFile(szKeyFile,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Unable to open key file\n");
__leave;
}
// Get file length
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -