//-------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. // Example of signing a hash and // verifying the hash signature. #pragma comment(lib, "crypt32.lib") #include <stdio.h> #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) void MyHandleError(char *s); void main(void) { //------------------------------------------------------------------- // Declare and initialize variables. HCRYPTPROV hProv; BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed."; DWORD dwBufferLen = strlen((char *)pbBuffer)+1; HCRYPTHASH hHash; HCRYPTKEY hKey; HCRYPTKEY hPubKey; BYTE *pbKeyBlob; BYTE *pbSignature; DWORD dwSigLen; DWORD dwBlobLen; //------------------------------------------------------------------- // Acquire a cryptographic provider context handle. if(CryptAcquireContext( &hProv, NULL, NULL, PROV_RSA_FULL, 0)) { printf("CSP context acquired.\n"); } else { MyHandleError("Error during CryptAcquireContext."); } //------------------------------------------------------------------- // Get the public at signature key. This is the public key // that will be used by the receiver of the hash to verify // the signature. In situations where the receiver could obtain the // sender's public key from a certificate, this step would not be // needed. if(CryptGetUserKey( hProv, AT_SIGNATURE, &hKey)) { printf("The signature key has been acquired. \n"); } else { MyHandleError("Error during CryptGetUserKey for signkey."); } //------------------------------------------------------------------- // Export the public key. Here the public key is exported to a // PUBLICKEYBOLB so that the receiver of the signed hash can // verify the signature. This BLOB could be written to a file and // sent to another user. if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) { printf("Size of the BLOB for the public key determined. \n"); } else { MyHandleError("Error computing BLOB length."); } //------------------------------------------------------------------- // Allocate memory for the pbKeyBlob. if(pbKeyBlob = (BYTE*)malloc(dwBlobLen)) { printf("Memory has been allocated for the BLOB. \n"); } else { MyHandleError("Out of memory. \n"); } //------------------------------------------------------------------- // Do the actual exporting into the key BLOB. if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) { printf("Contents have been written to the BLOB. \n"); } else { MyHandleError("Error during CryptExportKey."); } //------------------------------------------------------------------- // Create the hash object. if(CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash)) { printf("Hash object created. \n"); } else { MyHandleError("Error during CryptCreateHash."); } //------------------------------------------------------------------- // Compute the cryptographic hash of the buffer. if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { printf("The data buffer has been hashed.\n"); } else { MyHandleError("Error during CryptHashData."); } //------------------------------------------------------------------- // Determine the size of the signature and allocate memory. dwSigLen= 0; if(CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSigLen)) { printf("Signature length %d found.\n",dwSigLen); } else { MyHandleError("Error during CryptSignHash."); } //------------------------------------------------------------------- // Allocate memory for the signature buffer. if(pbSignature = (BYTE *)malloc(dwSigLen)) { printf("Memory allocated for the signature.\n"); } else { MyHandleError("Out of memory."); } //------------------------------------------------------------------- // Sign the hash object. if(CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen)) { printf("pbSignature is the hash signature.\n"); } else { MyHandleError("Error during CryptSignHash."); } //------------------------------------------------------------------- // Destroy the hash object. if(hHash) CryptDestroyHash(hHash); printf("The hash object has been destroyed.\n"); printf("The signing phase of this program is completed.\n\n"); //------------------------------------------------------------------- // In the second phase, the hash signature is verified. // This would most often be done by a different user in a // separate program. The hash, signature, and the PUBLICKEYBLOB // would be read from a file, an email message, // or some other source. // Here, the original pbBuffer, pbSignature, szDescription. // pbKeyBlob, and their lengths are used. // The contents of the pbBuffer must be the same data // that was originally signed. //------------------------------------------------------------------- // Get the public key of the user who created the digital signature // and import it into the CSP by using CryptImportKey. This returns // a handle to the public key in hPubKey. if(CryptImportKey( hProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey)) { printf("The key has been imported.\n"); } else { MyHandleError("Public key import failed."); } //------------------------------------------------------------------- // Create a new hash object. if(CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash)) { printf("The hash object has been recreated. \n"); } else { MyHandleError("Error during CryptCreateHash."); } //------------------------------------------------------------------- // Compute the cryptographic hash of the buffer. if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { printf("The new hash has been created.\n"); } else { MyHandleError("Error during CryptHashData."); } //------------------------------------------------------------------- // Validate the digital signature. if(CryptVerifySignature( hHash, pbSignature, dwSigLen, hPubKey, NULL, 0)) { printf("The signature has been verified.\n"); } else { printf("Signature not validated!\n"); } //------------------------------------------------------------------- // Free memory to be used to store signature. if(pbSignature) free(pbSignature); //------------------------------------------------------------------- // Destroy the hash object. if(hHash) CryptDestroyHash(hHash); //------------------------------------------------------------------- // Release the provider handle. if(hProv) CryptReleaseContext(hProv, 0); } // End of main //------------------------------------------------------------------- // This example uses the function MyHandleError, a simple error // handling function, to print an error message to the // standard error (stderr) file and exit the program. // For most applications, replace this function with one // that does more extensive error reporting. void MyHandleError(char *s) { fprintf(stderr,"An error occurred in running the program. \n"); fprintf(stderr,"%s\n",s); fprintf(stderr, "Error number %x.\n", GetLastError()); fprintf(stderr, "Program terminating. \n"); exit(1); } // End of MyHandleError
Write, Run & Share C Language code online using OneCompiler's C online compiler for free. It's one of the robust, feature-rich online compilers for C language, running the latest C version which is C18. Getting started with the OneCompiler's C editor is really simple and pretty fast. The editor shows sample boilerplate code when you choose language as 'C' and start coding!
OneCompiler's C online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample C program which takes name as input and print your name with hello.
#include <stdio.h>
int main()
{
char name[50];
printf("Enter name:");
scanf("%s", name);
printf("Hello %s \n" , name );
return 0;
}
C language is one of the most popular general-purpose programming language developed by Dennis Ritchie at Bell laboratories for UNIX operating system. The initial release of C Language was in the year 1972. Most of the desktop operating systems are written in C Language.
When ever you want to perform a set of operations based on a condition if-else
is used.
if(conditional-expression) {
// code
} else {
// code
}
You can also use if-else for nested Ifs and if-else-if ladder when multiple conditions are to be performed on a single variable.
Switch is an alternative to if-else-if ladder.
switch(conditional-expression) {
case value1:
// code
break; // optional
case value2:
// code
break; // optional
...
default:
// code to be executed when all the above cases are not matched;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement){
// code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while(condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Array is a collection of similar data which is stored in continuous memory addresses. Array values can be fetched using index. Index starts from 0 to size-1.
data-type array-name[size];
data-type array-name[size][size];
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity.
Two types of functions are present in C
Library functions are the in-built functions which are declared in header files like printf(),scanf(),puts(),gets() etc.,
User defined functions are the ones which are written by the programmer based on the requirement.
return_type function_name(parameters);
function_name (parameters)
return_type function_name(parameters) {
//code
}