static void updateConfigCert( void ) { CRYPT_CERTIFICATE trustedCert; int status; /* Import the first certificate, make it trusted, and commit the changes */ importCertFromTemplate( &trustedCert, CERT_FILE_TEMPLATE, 1 ); cryptSetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT, TRUE ); cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CONFIGCHANGED, FALSE ); cryptDestroyCert( trustedCert ); cryptEnd(); /* Do the same with a second certificate. At the conclusion of this, we should have two trusted certificates on disk */ status = cryptInit(); if( cryptStatusError( status ) ) { puts( "Couldn't reload cryptlib configuration." ); return; } importCertFromTemplate( &trustedCert, CERT_FILE_TEMPLATE, 2 ); cryptSetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT, TRUE ); cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CONFIGCHANGED, FALSE ); cryptDestroyCert( trustedCert ); cryptEnd(); }
static void testKludge( const char *argPtr ) { #if 0 testReadCorruptedKey(); #endif /* 0 */ /* To test dodgy certificate collections */ #if 0 int result; if( argPtr == NULL ) { printf( "Error: Missing argument.\n" ); exit( EXIT_FAILURE ); } if( *argPtr == '@' ) { cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL, CRYPT_COMPLIANCELEVEL_OBLIVIOUS ); argPtr++; } if( *argPtr == '#' ) { cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL, CRYPT_COMPLIANCELEVEL_PKIX_FULL ); argPtr++; } result = xxxCertImport( argPtr ); cryptEnd(); exit( result ? EXIT_SUCCESS : EXIT_FAILURE ); #endif /* 1 */ /* Performance-testing test harness */ #if 0 void performanceTests( const CRYPT_DEVICE cryptDevice ); performanceTests( CRYPT_UNUSED ); #endif /* 0 */ /* Memory diagnostic test harness */ #if 0 testReadFileCertPrivkey(); testEnvelopePKCCrypt(); /* Use "Datasize, certificate" */ testEnvelopeSign(); /* Use "Datasize, certificate" */ #endif /* 0 */ /* Simple (brute-force) server code. NB: Remember to change setLocalConnect() to not bind the server to localhost if expecting external connections */ #if 0 while( TRUE ) testSessionTSPServer(); #endif /* 0 */ /* Exit point for the test harnesses above, used when we don't want to fall through to the main test code */ #if 0 cleanupAndExit( EXIT_SUCCESS ); #endif /* 0 */ }
static int create_selfsigned_cert(CRYPT_CONTEXT ca_key_pair, const char *dn, /* out */ CRYPT_CERTIFICATE *pCert) { CRYPT_CERTIFICATE result_certificate; int status; /* create the certificate and associate it with the CA's pubkey */ status = cryptCreateCert(&result_certificate, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTIFICATE); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while creating CA selfsigned cert\n", status); return status; } status = cryptSetAttribute(result_certificate, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, ca_key_pair); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while associating CA cert with key\n", status); goto err_cert_exit; } /* set the DN */ cryptSetAttributeString(result_certificate, CRYPT_CERTINFO_DN, dn, strlen(dn)); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while setting CA cert DN\n", status); goto err_cert_exit; } /* set self-signed and CA bits */ status = cryptSetAttribute(result_certificate, CRYPT_CERTINFO_SELFSIGNED, 1); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while setting CA cert selfsigned bit\n", status); goto err_cert_exit; } status = cryptSetAttribute(result_certificate, CRYPT_CERTINFO_CA, 1); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while setting CA cert CA bit\n", status); goto err_cert_exit; } /* set implicit trust bit */ status = cryptSetAttribute(result_certificate, CRYPT_CERTINFO_TRUSTED_USAGE, CRYPT_KEYUSAGE_KEYCERTSIGN | CRYPT_KEYUSAGE_CRLSIGN); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while setting CA cert implicit trust bit\n", status); goto err_cert_exit; } /* sign it */ status = cryptSignCert(result_certificate, ca_key_pair); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while self-signing CA cert\n", status); goto err_cert_exit; } *pCert = result_certificate; return CRYPT_OK; err_cert_exit: cryptDestroyCert(result_certificate); return status; }
static int checkKeysetCRL( const CRYPT_KEYSET cryptKeyset, const CRYPT_CERTIFICATE cryptCert, const BOOLEAN isCertChain ) { int errorLocus, status; /* Perform a revocation check against the CRL in the keyset */ printf( "Checking certificate%s against CRL.\n", isCertChain ? " chain" : "" ); status = cryptCheckCert( cryptCert, cryptKeyset ); if( cryptStatusOK( status ) ) return( TRUE ); if( isCertChain ) { /* Checking a chain against a keyset doesn't really make sense, so this should be rejected */ if( status == CRYPT_ERROR_PARAM2 ) return( TRUE ); printf( "Check of certificate chain against keyset returned %d, " "should have been %d.\n", status, CRYPT_ERROR_PARAM2 ); return( FALSE ); } if( status != CRYPT_ERROR_INVALID ) { return( extErrorExit( cryptKeyset, "cryptCheckCert() (for CRL in " "keyset)", status, __LINE__ ) ); } /* If the certificate has expired then it'll immediately be reported as invalid without bothering to check the CRL, so we have to perform the check in oblivious mode to avoid the expiry check */ status = cryptGetAttribute( cryptCert, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus ); if( cryptStatusOK( status ) && errorLocus == CRYPT_CERTINFO_VALIDTO ) { int complianceValue; puts( " (Certificate has already expired, re-checking in oblivious " "mode)." ); ( void ) cryptGetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL, &complianceValue ); cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL, CRYPT_COMPLIANCELEVEL_OBLIVIOUS ); status = cryptCheckCert( cryptCert, cryptKeyset ); cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL, complianceValue ); } if( cryptStatusError( status ) ) return( extErrorExit( cryptKeyset, "cryptCheckCert() (for CRL in " "keyset)", status, __LINE__ ) ); return( TRUE ); }
static int add_ca_cert_to_store(CRYPT_KEYSET store, const char *dn, CRYPT_CERTIFICATE cert) { int status; CRYPT_CERTIFICATE pki_user; status = cryptCreateCert(&pki_user, CRYPT_UNUSED, CRYPT_CERTTYPE_PKIUSER); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(pki_user, CRYPT_CERTINFO_DN, dn, strlen(dn)); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(pki_user, CRYPT_CERTINFO_CA, 1); WARN_AND_RETURN_IF(status); status = cryptCAAddItem(store, pki_user); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(pki_user); WARN_AND_RETURN_IF(status); status = cryptCAAddItem(store, cert); if (!cryptStatusOK(status)) { int errorLocus; int errorType; cryptGetAttribute(store, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus); cryptGetAttribute(store, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType); fprintf(stderr, "locus %d type %d\n", errorLocus, errorType); cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus); cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType); fprintf(stderr, "locus %d type %d\n", errorLocus, errorType); } WARN_AND_RETURN_IF(status); return CRYPT_OK; }
unsigned __stdcall envelopeDataThread( void *arg ) #endif /* Different threading models */ { static const char *envData = "qwertyuiopasdfghjklzxcvbnm"; BYTE fileBuffer[ BUFFER_SIZE ]; const unsigned uThread = ( unsigned ) arg; const time_t startTime = time( NULL ); int count, status; printf( "Thread %d started.\n", uThread ); fflush( stdout ); filenameFromTemplate( fileBuffer, CERT_FILE_TEMPLATE, 13 ); for( count = 0; count < 150; count++ ) { CRYPT_ENVELOPE cryptEnvelope; CRYPT_CERTIFICATE cryptCert; BYTE envBuffer[ BUFFER_SIZE ]; int bytesCopied; /* Create the cert and envelope and add the cert to the envelope */ status = importCertFile( &cryptCert, fileBuffer ); if( cryptStatusOK( status ) ) status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, CRYPT_FORMAT_CRYPTLIB ); if( cryptStatusOK( status ) ) status = cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_PUBLICKEY, cryptCert ); if( cryptStatusError( status ) ) break; /* Envelope data and destroy the envelope */ status = cryptPushData( cryptEnvelope, envData, strlen( envData ), &bytesCopied ); if( cryptStatusOK( status ) ) status = cryptPushData( cryptEnvelope, NULL, 0, NULL ); if( cryptStatusOK( status ) ) status = cryptPopData( cryptEnvelope, envBuffer, BUFFER_SIZE, &bytesCopied ); if( cryptStatusOK( status ) ) status = cryptDestroyEnvelope( cryptEnvelope ); if( cryptStatusError( status ) ) break; printf( "%c", uThread + '0' ); } printf( "Thread %u exited after %d seconds.\n", uThread, time( NULL ) - startTime ); fflush( stdout ); #ifdef UNIX_THREADS pthread_exit( NULL ); #else _endthreadex( 0 ); #endif /* Different threading models */ return( 0 ); }
int main( int argc, char **argv) { CRYPT_CONTEXT privKeyContext; CRYPT_KEYSET cryptKeyset; int ksize; if (argc < 3) { fprintf(stderr, "Usage: %s filename keysize\n", argv[0]); return 1; } if (sscanf(argv[2], "%d", &ksize) != 1) { fprintf(stderr, "Invalid key size\n"); return 1; } if (ksize != STANDARD_KEY_SIZE) { fprintf(stderr, "Warning: key size %d is not the standard size (%d)\n", ksize, STANDARD_KEY_SIZE); } printf("Making %s with key size %d bits \n", argv[1], ksize); if (cryptInit() != CRYPT_OK) { fprintf(stderr, "Can't open Cryptlib\n"); return 1; } if (cryptCreateContext(&privKeyContext, CRYPT_UNUSED, CRYPT_ALGO_RSA) != CRYPT_OK) { fprintf(stderr, "Can't create cryptlib private key context\n"); return 1; } cryptSetAttributeString(privKeyContext, CRYPT_CTXINFO_LABEL, "label", 5); cryptSetAttribute(privKeyContext, CRYPT_CTXINFO_KEYSIZE, ksize / 8); if (cryptGenerateKey(privKeyContext) != CRYPT_OK) { fprintf(stderr, "Can't generate key\n"); return 1; } if (cryptKeysetOpen(&cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, argv[1], CRYPT_KEYOPT_CREATE) != CRYPT_OK) { fprintf(stderr, "Can't open keyset\n"); return 1; } if (cryptAddPrivateKey(cryptKeyset, privKeyContext, "password") != CRYPT_OK) { fprintf(stderr, "Can't add key to keyset\n"); return 1; } cryptKeysetClose(cryptKeyset); cryptDestroyContext(privKeyContext); cryptEnd(); return 0; }
unsigned __stdcall encTest( void *arg ) { CRYPT_ENVELOPE cryptEnvelope; CRYPT_CERTIFICATE cryptCert; BYTE buffer[ 1024 ]; const int count = *( ( int * ) arg ); int bytesCopied, i, status; printf( "EncTest %d.\n", count ); for( i = 0; i < count; i++ ) { FILE *filePtr; int certSize; if( ( filePtr = fopen( "testdata/cert5.der", "rb" ) ) != NULL ) { certSize = fread( buffer, 1, 1024, filePtr ); fclose( filePtr ); } status = cryptImportCert( buffer, certSize, CRYPT_UNUSED, &certificate ); if( cryptStatusOK( status ) ) status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, CRYPT_FORMAT_CMS ); if( cryptStatusOK( status ) ) status = cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_PUBLICKEY, cryptCert ); if( cryptStatusOK( status ) ) status = cryptPushData( cryptEnvelope, buffer, 200, &bytesCopied ); if( cryptStatusOK( status ) ) status = cryptFlushData( cryptEnvelope ); if( cryptStatusOK( status ) ) status = cryptPopData( cryptEnvelope, buffer, 1024, &bytesCopied ); if( cryptStatusOK( status ) ) status = cryptDestroyCert( cryptCert ); if( cryptStatusOK( status ) ) status = cryptDestroyEnvelope( cryptEnvelope ); if( cryptStatusError( status ) ) { _endthreadex( status ); return( 0 ); } } _endthreadex( 0 ); return( 0 ); }
unsigned __stdcall signTest( void *arg ) { CRYPT_KEYSET cryptKeyset; CRYPT_CONTEXT privateKeyContext; CRYPT_ENVELOPE cryptEnvelope; BYTE buffer[ 1024 ]; const int count = *( ( int * ) arg ); int bytesCopied, i, status; printf( "SignTest %d.\n", count ); for( i = 0; i < count; i++ ) { status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, TEST_PRIVKEY_FILE, CRYPT_KEYOPT_READONLY); if( cryptStatusOK( status ) ) status = cryptGetPrivateKey( cryptKeyset, &privateKeyContext, CRYPT_KEYID_NAME, RSA_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD ); if( cryptStatusOK( status ) ) status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, CRYPT_FORMAT_CMS ); if( cryptStatusOK( status ) ) status = cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_SIGNATURE, privateKeyContext ); if( cryptStatusOK( status ) ) status = cryptPushData( cryptEnvelope, "message", 7, &bytesCopied ); if( cryptStatusOK( status ) ) status = cryptFlushData( cryptEnvelope ); if( cryptStatusOK( status ) ) status = cryptPopData( cryptEnvelope, buffer, 1024, &bytesCopied ); if( cryptStatusOK( status ) ) status = cryptDestroyContext( privateKeyContext ); if( cryptStatusOK( status ) ) status = cryptKeysetClose( cryptKeyset ); if( cryptStatusOK( status ) ) status = cryptDestroyEnvelope( cryptEnvelope ); if( cryptStatusError( status ) ) { _endthreadex( status ); return( 0 ); } } _endthreadex( 0 ); return( 0 ); }
/* * int fatal(char *msg) { if (msg && *msg) fprintf(stderr, "%s\n", msg); * exit(0); } */ int main( int argc, char **argv) { CRYPT_CONTEXT privKeyContext; CRYPT_KEYSET cryptKeyset; if (argc < 2) { fprintf(stderr, "Usage: Filename\n"); return 1; } printf("Making %s\n", argv[1]); #define CRYPT_CALL(f) \ do \ { \ if ((f) != CRYPT_OK) \ { \ fprintf(stderr, "Error calling %s\n", #f); \ exit(EXIT_FAILURE); \ } \ } while (false) CRYPT_CALL(cryptInit()); CRYPT_CALL(cryptCreateContext(&privKeyContext, CRYPT_UNUSED, CRYPT_ALGO_RSA)); CRYPT_CALL(cryptSetAttributeString(privKeyContext, CRYPT_CTXINFO_LABEL, "label", 5)); CRYPT_CALL(cryptSetAttribute(privKeyContext, CRYPT_CTXINFO_KEYSIZE, 1024 / 8)); CRYPT_CALL(cryptGenerateKey(privKeyContext)); CRYPT_CALL(cryptKeysetOpen(&cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, argv[1], CRYPT_KEYOPT_CREATE)); CRYPT_CALL(cryptAddPrivateKey(cryptKeyset, privKeyContext, "password")); CRYPT_CALL(cryptKeysetClose(cryptKeyset)); CRYPT_CALL(cryptDestroyContext(privKeyContext)); CRYPT_CALL(cryptEnd()); #undef CRYPT_CALL return 0; }
static int connectTSP( const CRYPT_SESSION_TYPE sessionType, const CRYPT_HANDLE externalCryptContext, const BOOLEAN persistentConnection, const BOOLEAN localSession ) { CRYPT_SESSION cryptSession; const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_TSP_SERVER ) ? \ TRUE : FALSE; const BOOLEAN useAltHash = ( !isServer && 0 ) ? TRUE : FALSE; int status; printf( "%sTesting %sTSP session...\n", isServer ? "SVR: " : "", localSession ? "local " : "" ); /* Acquire the init mutex if we're the server */ if( localSession && isServer ) waitMutex(); /* Create the TSP session */ status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType ); if( status == CRYPT_ERROR_PARAM3 ) /* TSP session access not available */ return( CRYPT_ERROR_NOTAVAIL ); if( cryptStatusError( status ) ) { printf( "%scryptCreateSession() failed with error code %d, line " "%d.\n", isServer ? "SVR: " : "", status, __LINE__ ); return( FALSE ); } /* Set up the server information and activate the session. Since this test explicitly tests the ability to handle persistent connections, we don't use the general-purpose request/response server wrapper, which only uses persistent connections opportunistically */ if( isServer ) { CRYPT_CONTEXT privateKey = externalCryptContext; if( !setLocalConnect( cryptSession, 318 ) ) return( FALSE ); if( externalCryptContext == CRYPT_UNUSED ) status = getPrivateKey( &privateKey, TSA_PRIVKEY_FILE, USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD ); if( cryptStatusOK( status ) ) { status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_PRIVATEKEY, privateKey ); if( externalCryptContext == CRYPT_UNUSED ) cryptDestroyContext( privateKey ); } } else { if( localSession ) { if( !setLocalConnect( cryptSession, 318 ) ) return( FALSE ); } else { status = cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_SERVER_NAME, TSP_SERVER_NAME, paramStrlen( TSP_SERVER_NAME ) ); } } if( cryptStatusError( status ) ) { printf( "cryptSetAttribute/cryptSetAttributeString() failed with " "error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } status = testTSP( cryptSession, isServer, FALSE, useAltHash, localSession ); if( status <= 0 ) return( status ); /* Check whether the session connection is still open */ if( persistentConnection ) { int connectionActive; status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_CONNECTIONACTIVE, &connectionActive ); if( cryptStatusError( status ) || !connectionActive ) { printExtError( cryptSession, isServer ? \ "SVR: Persistent connection has been closed, " "operation" : \ "Persistent connection has been closed, operation", status, __LINE__ ); return( FALSE ); } /* Activate the connection to handle two more requests */ status = testTSP( cryptSession, isServer, TRUE, FALSE, FALSE ); if( status <= 0 ) return( status ); status = testTSP( cryptSession, isServer, TRUE, FALSE, FALSE ); if( status <= 0 ) return( status ); } /* Clean up */ status = cryptDestroySession( cryptSession ); if( cryptStatusError( status ) ) { printf( "cryptDestroySession() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } printf( isServer ? "SVR: %sTSP server session succeeded.\n\n" : \ "%sTSP client session succeeded.\n\n", persistentConnection ? "Persistent " : "" ); return( TRUE ); }
static int exec_revoke(int argc, char **argv) { const char *id, *dbfilename, *pass; char cakeysfilename[4096]; CRYPT_KEYID_TYPE id_type; CRYPT_KEYSET store, cakeys; CRYPT_CERTIFICATE cert, crl; CRYPT_CONTEXT ca_privkey; int status; if (argc != 4) { fprintf(stderr, "usage: revoke dbfile (-e email | -n name) pass\n"); return 1; } dbfilename = argv[0]; id = argv[2]; pass = argv[3]; if (strcmp(argv[1], "-e") == 0) { id_type = CRYPT_KEYID_EMAIL; } else if (strcmp(argv[1], "-n") == 0) { id_type = CRYPT_KEYID_NAME; } else { fprintf(stderr, "usage: revoke dbfile (-e email | -n name)\n"); return 1; } /* open store */ status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE); WARN_AND_RETURN_IF(status); /* get ca privkey */ snprintf(cakeysfilename, 4095, "%s.keys", dbfilename); status = cryptKeysetOpen(&cakeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, cakeysfilename, CRYPT_KEYOPT_NONE); WARN_AND_RETURN_IF(status); status = cryptGetPrivateKey(cakeys, &ca_privkey, CRYPT_KEYID_NAME, DEFAULT_CA_PRIVKEY_LABEL, DEFAULT_PASSWORD); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(cakeys); WARN_AND_RETURN_IF(status); /* get cert to revoke */ status = cryptCAGetItem(store, &cert, CRYPT_CERTTYPE_CERTIFICATE, id_type, id); WARN_AND_RETURN_IF(status); /* create CRL */ status = cryptCreateCert(&crl, CRYPT_UNUSED, CRYPT_CERTTYPE_CRL); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(crl, CRYPT_CERTINFO_CERTIFICATE, cert); WARN_AND_RETURN_IF(status); status = cryptSignCert(crl, ca_privkey); WARN_AND_RETURN_IF(status); status = cryptAddPublicKey(store, crl); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(crl); WARN_AND_RETURN_IF(status); status = cryptDestroyContext(ca_privkey); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(store); WARN_AND_RETURN_IF(status); return 0; }
static int testProcessing( const CRYPT_ALGO_TYPE cryptAlgo, const CRYPT_MODE_TYPE cryptMode, const CRYPT_QUERY_INFO cryptQueryInfo ) { BYTE buffer1[ DATABUFFER_SIZE ], buffer2[ DATABUFFER_SIZE ]; BYTE hash1[ CRYPT_MAX_HASHSIZE ], hash2[ CRYPT_MAX_HASHSIZE ]; const int blockSize = ( cryptMode == CRYPT_MODE_ECB || \ cryptMode == CRYPT_MODE_CBC ) ? \ cryptQueryInfo.blockSize : 1; int length1, length2, i; /* Initialise the buffers with a known data pattern */ memset( buffer1, '*', DATABUFFER_SIZE ); memcpy( buffer1, "12345678", 8 ); memcpy( buffer2, buffer1, DATABUFFER_SIZE ); /* Process the data using various block sizes */ printf( "Testing algorithm %d, mode %d, for %d-byte buffer with\n block " "count ", cryptAlgo, ( cryptMode == CRYPT_UNUSED ) ? 0 : cryptMode, DATABUFFER_SIZE ); for( i = 1; i <= MAX_BLOCKS; i++ ) { CRYPT_CONTEXT cryptContext; int status; memcpy( buffer1, buffer2, DATABUFFER_SIZE ); printf( "%d%s ", i, ( i == MAX_BLOCKS ) ? "." : "," ); /* Encrypt the data with random block sizes */ status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo ); if( cryptStatusError( status ) ) return( status ); if( cryptMode != CRYPT_UNUSED ) { status = cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE, cryptMode ); if( cryptStatusError( status ) ) return( status ); if( cryptMode != CRYPT_MODE_ECB && cryptAlgo != CRYPT_ALGO_RC4 ) { status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_IV, "1234567887654321", cryptQueryInfo.blockSize ); if( cryptStatusError( status ) ) return( status ); } } if( cryptQueryInfo.keySize ) { status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY, "12345678876543211234567887654321", cryptQueryInfo.keySize ); if( cryptStatusError( status ) ) return( status ); } status = processData( cryptContext, buffer1, i, blockSize, cryptEncrypt ); if( cryptStatusError( status ) ) return( status ); if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH ) { status = cryptGetAttributeString( cryptContext, CRYPT_CTXINFO_HASHVALUE, hash1, &length1 ); if( cryptStatusError( status ) ) return( status ); } status = cryptDestroyContext( cryptContext ); if( cryptStatusError( status ) ) return( status ); /* Decrypt the data again with random block sizes */ status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo ); if( cryptStatusError( status ) ) return( status ); if( cryptMode != CRYPT_UNUSED ) { status = cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE, cryptMode ); if( cryptStatusError( status ) ) return( status ); if( cryptMode != CRYPT_MODE_ECB && cryptAlgo != CRYPT_ALGO_RC4 ) { status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_IV, "1234567887654321", cryptQueryInfo.blockSize ); if( cryptStatusError( status ) ) return( status ); } } if( cryptQueryInfo.keySize ) { status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY, "12345678876543211234567887654321", cryptQueryInfo.keySize ); if( cryptStatusError( status ) ) return( status ); } status = processData( cryptContext, buffer1, i, blockSize, cryptDecrypt ); if( cryptStatusError( status ) ) return( status ); if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH ) { status = cryptGetAttributeString( cryptContext, CRYPT_CTXINFO_HASHVALUE, hash2, &length2 ); if( cryptStatusError( status ) ) return( status ); } status = cryptDestroyContext( cryptContext ); if( cryptStatusError( status ) ) return( status ); /* Make sure the values match */ if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH ) { if( ( length1 != length2 ) || memcmp( hash1, hash2, length1 ) ) { puts( "Error: Hash value of identical buffers differs." ); return( -1234 ); } } else if( memcmp( buffer1, buffer2, DATABUFFER_SIZE ) ) { printf( "Decrypted data != encrypted data for algorithm %d.\n", cryptAlgo ); return( -1234 ); } } printf( "\n" ); return( CRYPT_OK ); }
int main(int argc, char const *argv[]) { struct passwd *pws; /* info for input user */ char *pwname; /* username */ char *pwdir; /* home directory */ char *encFile; char *encKey; int encKeyFd; //file state char *encKeyPtr; /* Pointer to encrypted data */ int encKeySize; /* Buffer bytes availble for decrypt */ struct stat fileStat; /* Struce for checking file attributes */ char *keyFile; /* GPG key ring file name */ char *gpgPrivateKeyPtr; int ret; /* Return code */ int i; /* Loop iterator */ int bytesCopied; /* Bytes output by cryptlib enc/dec ops */ int reqAttrib; /* Crypt required attributed */ CRYPT_ENVELOPE dataEnv; /* Envelope for enc/dec */ CRYPT_KEYSET keyset; /* GPG keyset */ CRYPT_CONTEXT symContext; /* Key context */ char label[100]; /* Private key label */ int labelLength; /* Length of label */ char passbuf[1024]; /* Buffer for GPG key passphrase */ struct termios ts, ots; /* Strutures for saving/modifying term attribs */ char *encDataPtr; /* Pointer to encrypted data */ int encDataSize; /* Size of encrypted data */ struct passwd *userInfo; /* Password info for input user */ int encFileFd; /* Destination (Encrypted) File Descriptor */ int encFileSize; /* Bytes of encrypted data */ char * encFilePtr; /* Pointer to enc text */ char *clrFilePtr; /* Pointer to clear text */ int clrFileSize; /* Bytes of clear text */ char *clrKeyPtr; int clrKeySize; struct stat encFileInfo; uid = getuid(); pws = getpwuid(uid); pwname = pws->pw_name;//get the user login name; pwdir = pws->pw_dir;//get the user dir path //Check arguments number if (argc!=2) { printf("slient exit\n"); exit (1); } //Get encrepted file encFile = malloc(strlen(argv[1]) + 4); strcpy(encFile, argv[1]); strcat(encFile, ".enc"); //Get gpg encrepted key name encKey = malloc(strlen(encFile) + strlen(pwname) +5 ); strcpy(encKey,encFile); strcat(encKey, "."); strcat(encKey, pwname); strcat(encKey, ".key"); //Open gpg encrepted key encKeyFd=open(encKey, O_RDONLY); if (encKeyFd<=0){perror("(2) open encKeyFd2");exit(encKeyFd);} ret=fstat(encKeyFd,&fileStat); if (ret!=0){perror("fstat encKeyFd");exit(ret);} encKeySize=fileStat.st_size; encKeyPtr=malloc(encKeySize); if (encKeyPtr==NULL){perror("malloc encData");exit(__LINE__);} ret=read(encKeyFd,encKeyPtr,encKeySize); if (ret!=encKeySize){perror("read encData");exit(ret);} close(encKeyFd); //Get the private key name gpgPrivateKeyPtr=malloc(strlen(pwdir) + strlen("/.gnupg/secring.gpg") + 1); getPrivateKeyName(gpgPrivateKeyPtr,uid); //Decrypt key cryptInit(); ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL); checkCryptNormal(ret,"cryptAddRandom",__LINE__); ret=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, gpgPrivateKeyPtr, CRYPT_KEYOPT_READONLY); free(gpgPrivateKeyPtr); checkCryptNormal(ret,"cryptKeysetOpen",__LINE__); ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_AUTO); checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__); ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_KEYSET_DECRYPT, keyset); checkCryptNormal(ret,"cryptSetAttribute",__LINE__); ret=cryptPushData(dataEnv,encKeyPtr,encKeySize,&bytesCopied); /* Expect non-zero return -- indicates need private key */ ret=cryptGetAttribute(dataEnv, CRYPT_ATTRIBUTE_CURRENT, &reqAttrib); if (reqAttrib != CRYPT_ENVINFO_PRIVATEKEY) {printf("Decrypt error\n");exit(ret);} ret=cryptGetAttributeString(dataEnv, CRYPT_ENVINFO_PRIVATEKEY_LABEL, label, &labelLength); label[labelLength]='\0'; checkCryptNormal(ret,"cryptGetAttributeString",__LINE__); /*=============================================== Get the passphrase =============================================== */ tcgetattr(STDIN_FILENO, &ts); ots = ts; ts.c_lflag &= ~ECHO; ts.c_lflag |= ECHONL; tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts); tcgetattr(STDIN_FILENO, &ts); if (ts.c_lflag & ECHO) { fprintf(stderr, "Failed to turn off echo\n"); tcsetattr(STDIN_FILENO, TCSANOW, &ots); exit(1); } printf("Enter password for <%s>: ",label); fflush(stdout); fgets(passbuf, 1024, stdin); tcsetattr(STDIN_FILENO, TCSANOW, &ots); ret=cryptSetAttributeString(dataEnv, CRYPT_ENVINFO_PASSWORD, passbuf, strlen(passbuf)-1); if (ret != CRYPT_OK) { if (ret=CRYPT_ERROR_WRONGKEY) { printf("Wrong Key\n"); exit(ret); }else{ printf("cryptSetAttributeString line %d returned <%d>\n",__LINE__,ret); exit(ret); } } ret=cryptFlushData(dataEnv); checkCryptNormal(ret,"cryptFlushData",__LINE__); clrKeySize=KEYSIZE; clrKeyPtr=malloc(clrKeySize); if (clrKeyPtr==NULL){perror("malloc");exit(__LINE__);} bzero(clrKeyPtr,clrKeySize); ret=cryptPopData(dataEnv,clrKeyPtr,clrKeySize,&bytesCopied); checkCryptNormal(ret,"cryptPopData",__LINE__); ret=cryptDestroyEnvelope(dataEnv); checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__); cryptKeysetClose(keyset); checkCryptNormal(ret,"cryptKeysetClose",__LINE__); printf("Bytes decrypted <%d>\n",bytesCopied); // for (i=0;i<bytesCopied;i++){printf("%c",clrKeyPtr[i]);} ret=cryptEnd(); checkCryptNormal(ret,"cryptEnd",__LINE__); //read enc file encFileFd=open(encFile, O_RDONLY); if (encFileFd<=0){perror("(2) open encFileFd1");exit(encFileFd);} ret=fstat(encFileFd,&encFileInfo); if (ret!=0){perror("fstat encFileFd");exit(ret);} encFileSize=encFileInfo.st_size; encFilePtr=malloc(encFileSize); if (encFilePtr==NULL){perror("malloc encData");exit(__LINE__);} ret=read(encFileFd,encFilePtr,encFileSize); if (ret!=encFileSize){perror("read encData");exit(ret);} close(encFileFd); //Decrypt and get the content of decrepted file cryptInit(); ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL); checkCryptNormal(ret,"cryptAddRandom",__LINE__); cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_AUTO); checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__); cryptPushData(dataEnv,encFilePtr,encFileSize,&bytesCopied); checkCryptNormal(ret,"cryptPushData",__LINE__); cryptCreateContext(&symContext,CRYPT_UNUSED,SYMMETRIC_ALG); checkCryptNormal(ret,"cryptCreateContext",__LINE__); cryptSetAttributeString(symContext, CRYPT_CTXINFO_KEY,clrKeyPtr,clrKeySize); checkCryptNormal(ret,"cryptSetAttributeString",__LINE__); cryptSetAttribute(dataEnv,CRYPT_ENVINFO_SESSIONKEY,symContext); checkCryptNormal(ret,"cryptSetAttribute",__LINE__); ret=cryptDestroyContext(symContext); checkCryptNormal(ret,"cryptDestroyContext",__LINE__); cryptFlushData(dataEnv); clrFileSize=KEYSIZE+1028; clrFilePtr=malloc(encDataSize); ret=cryptPopData(dataEnv,clrFilePtr,clrFileSize,&bytesCopied); checkCryptNormal(ret,"cryptPopData",__LINE__); ret=cryptDestroyEnvelope(dataEnv); checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__); printf("<%d> bytes of decrypted data\n",bytesCopied); for (i=0;i<bytesCopied;i++){printf("%c",clrFilePtr[i]);} printf("\n"); fflush(stdout); ret=cryptEnd(); checkCryptNormal(ret,"cryptEnd",__LINE__); return 0; }
static int exec_cmpsvr(int argc, char **argv) { CRYPT_KEYSET cakeys, store; CRYPT_SESSION session; CRYPT_CONTEXT ca_privkey; int status; const char *dbfilename = argv[0]; char cakeysfilename[4096]; /* PATH_MAX */ if (argc < 1) { fprintf(stderr, "missing dbfilename\n"); return 1; } status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP_SERVER); WARN_AND_RETURN_IF(status); /* open store */ status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE); WARN_AND_RETURN_IF(status); /* get ca privkey */ snprintf(cakeysfilename, 4095, "%s.keys", dbfilename); cakeysfilename[4095] = '\0'; status = cryptKeysetOpen(&cakeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, cakeysfilename, CRYPT_KEYOPT_NONE); WARN_AND_RETURN_IF(status); status = cryptGetPrivateKey(cakeys, &ca_privkey, CRYPT_KEYID_NAME, DEFAULT_CA_PRIVKEY_LABEL, DEFAULT_PASSWORD); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(cakeys); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_KEYSET, store); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_PRIVATEKEY, ca_privkey); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000); WARN_AND_RETURN_IF(status); fprintf(stderr, "before setting ACTIVE\n"); status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1); if (!cryptStatusOK(status)) { CRYPT_ERRTYPE_TYPE errtype; CRYPT_ATTRIBUTE_TYPE locus; char *errstring; int errstringlen; cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype); cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus); fprintf(stderr, "session errtype %d locus %d\n", errtype, locus); cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, NULL, &errstringlen); errstring = malloc(errstringlen + 10); cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, errstring, &errstringlen); errstring[errstringlen] = 0; fprintf(stderr, "session errmsg: %s\n", errstring); free(errstring); } WARN_AND_RETURN_IF(status); status = cryptKeysetClose(store); WARN_AND_RETURN_IF(status); status = cryptDestroyContext(ca_privkey); WARN_AND_RETURN_IF(status); status = cryptDestroySession(session); WARN_AND_RETURN_IF(status); return 0; }
void createCSR(CRYPT_CONTEXT keyContext) { CRYPT_CERTIFICATE cryptCertRequest; void *certRequest; int certRequestMaxLength, certRequestLength; FILE *f = NULL; int status; /* Create a certification request and add the public key to it */ status = cryptCreateCert( &cryptCertRequest, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTREQUEST ); if (status != CRYPT_OK) { fprintf(stderr, "Error creating certRequest\n"); exit(1); } status = cryptSetAttribute( cryptCertRequest, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, keyContext ); if (status != CRYPT_OK) { fprintf(stderr, "Error setting pubkey: %d\n", status); exit(1); } /* Add identification information */ status = cryptSetAttributeString(cryptCertRequest, CRYPT_CERTINFO_COUNTRYNAME, "US", 2); if (status != CRYPT_OK) { fprintf(stderr, "Error setting C\n"); exit(1); } status = cryptSetAttributeString(cryptCertRequest, CRYPT_CERTINFO_ORGANIZATIONNAME, "example", 7); if (status != CRYPT_OK) { fprintf(stderr, "Error setting O\n"); exit(1); } status = cryptSetAttributeString(cryptCertRequest, CRYPT_CERTINFO_COMMONNAME, "example", 7); if (status != CRYPT_OK) { fprintf(stderr, "Error setting CN\n"); exit(1); } /* Sign the certification request with the private key and export it */ status = cryptSignCert( cryptCertRequest, keyContext ); if (status != CRYPT_OK) { fprintf(stderr, "Error signing CSR\n"); exit(1); } status = cryptExportCert( NULL, 0, &certRequestMaxLength, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cryptCertRequest ); if (status != CRYPT_OK) { fprintf(stderr, "Error getting max cert length\n"); exit(1); } certRequest = malloc( certRequestMaxLength ); status = cryptExportCert( certRequest, certRequestMaxLength, &certRequestLength, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cryptCertRequest); if (status != CRYPT_OK) { fprintf(stderr, "Error exporting cert\n"); exit(1); } /* Destroy the certification request */ status = cryptDestroyCert( cryptCertRequest ); if (status != CRYPT_OK) { fprintf(stderr, "Error destroying cert request\n"); exit(1); } f = fopen(CSR_FILE, "w"); if (!f) { perror("fopen CSR_FILE"); exit(1); } fwrite(certRequest, certRequestLength, 1, f); fclose(f); free(certRequest); }
static int testKeysetWrite( const CRYPT_KEYSET_TYPE keysetType, const C_STR keysetName ) { CRYPT_KEYSET cryptKeyset; CRYPT_CERTIFICATE cryptCert; CRYPT_CONTEXT pubKeyContext, privKeyContext; C_CHR filenameBuffer[ FILENAME_BUFFER_SIZE ]; C_CHR name[ CRYPT_MAX_TEXTSIZE + 1 ]; int length, status; /* Import the certificate from a file - this is easier than creating one from scratch. We use one of the later certs in the test set, since this contains an email address, which the earlier ones don't */ status = importCertFromTemplate( &cryptCert, CERT_FILE_TEMPLATE, EMAILADDR_CERT_NO ); if( cryptStatusError( status ) ) { printf( "Couldn't read certificate from file, status %d, line %d.\n", status, __LINE__ ); return( FALSE ); } /* Make sure that the certificate does actually contain an email address */ status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_EMAIL, name, &length ); if( cryptStatusError( status ) ) { printf( "Certificate doesn't contain an email address and can't be " "used for testing,\n line %d.\n", __LINE__ ); return( FALSE ); } /* Create the database keyset with a check to make sure this access method exists so we can return an appropriate error message. If the database table already exists, this will return a duplicate data error so we retry the open with no flags to open the existing database keyset for write access */ status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, keysetType, keysetName, CRYPT_KEYOPT_CREATE ); if( cryptStatusOK( status ) ) printf( "Created new certificate database '%s'.\n", keysetName ); if( status == CRYPT_ERROR_PARAM3 ) { /* This type of keyset access isn't available, return a special error code to indicate that the test wasn't performed, but that this isn't a reason to abort processing */ cryptDestroyCert( cryptCert ); return( CRYPT_ERROR_NOTAVAIL ); } if( status == CRYPT_ERROR_DUPLICATE ) status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, keysetType, keysetName, 0 ); if( cryptStatusError( status ) ) { cryptDestroyCert( cryptCert ); printf( "cryptKeysetOpen() failed with error code %d, line %d.\n", status, __LINE__ ); if( status == CRYPT_ERROR_OPEN ) return( CRYPT_ERROR_FAILED ); return( FALSE ); } /* Write the key to the database */ puts( "Adding certificate." ); status = cryptAddPublicKey( cryptKeyset, cryptCert ); if( status == CRYPT_ERROR_DUPLICATE ) { /* The key is already present, delete it and retry the write */ status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_COMMONNAME, name, &length ); if( cryptStatusOK( status ) ) { #ifdef UNICODE_STRINGS length /= sizeof( wchar_t ); #endif /* UNICODE_STRINGS */ name[ length ] = TEXT( '\0' ); status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name ); } if( cryptStatusError( status ) ) return( extErrorExit( cryptKeyset, "cryptDeleteKey()", status, __LINE__ ) ); status = cryptAddPublicKey( cryptKeyset, cryptCert ); } if( cryptStatusError( status ) ) { printExtError( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ ); /* LDAP writes can fail due to the chosen directory not supporting the schema du jour, so we're a bit more careful about cleaning up since we'll skip the error and continue processing */ cryptDestroyCert( cryptCert ); cryptKeysetClose( cryptKeyset ); return( FALSE ); } cryptDestroyCert( cryptCert ); /* Add a second certificate with C=US so that we've got enough certs to properly exercise the query code. This certificate is highly unusual in that it doesn't have a DN, so we have to move up the DN looking for higher-up values, in this case the OU */ if( keysetType != CRYPT_KEYSET_LDAP ) { status = importCertFromTemplate( &cryptCert, CERT_FILE_TEMPLATE, 2 ); if( cryptStatusError( status ) ) { printf( "Couldn't read certificate from file, status %d, " "line %d.\n", status, __LINE__ ); return( FALSE ); } status = cryptAddPublicKey( cryptKeyset, cryptCert ); if( status == CRYPT_ERROR_DUPLICATE ) { status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_COMMONNAME, name, &length ); if( cryptStatusError( status ) ) status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, name, &length ); if( cryptStatusOK( status ) ) { #ifdef UNICODE_STRINGS length /= sizeof( wchar_t ); #endif /* UNICODE_STRINGS */ name[ length ] = TEXT( '\0' ); status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name ); } if( cryptStatusOK( status ) ) status = cryptAddPublicKey( cryptKeyset, cryptCert ); } if( cryptStatusError( status ) ) return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ ) ); cryptDestroyCert( cryptCert ); } /* Add a third certificate with a DN that'll cause problems for some storage technologies */ if( !loadRSAContexts( CRYPT_UNUSED, &pubKeyContext, &privKeyContext ) ) return( FALSE ); status = cryptCreateCert( &cryptCert, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTIFICATE ); if( cryptStatusError( status ) ) { printf( "cryptCreateCert() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } status = cryptSetAttribute( cryptCert, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, pubKeyContext ); if( cryptStatusError( status ) ) return( attrErrorExit( cryptCert, "cryptSetAttribute()", status, __LINE__ ) ); if( !addCertFields( cryptCert, sqlCertData, __LINE__ ) ) return( FALSE ); status = cryptSignCert( cryptCert, privKeyContext ); if( cryptStatusError( status ) ) return( attrErrorExit( cryptCert, "cryptSignCert()", status, __LINE__ ) ); destroyContexts( CRYPT_UNUSED, pubKeyContext, privKeyContext ); status = cryptAddPublicKey( cryptKeyset, cryptCert ); if( cryptStatusError( status ) ) { /* The key is already present, delete it and retry the write */ status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_COMMONNAME, name, &length ); if( cryptStatusOK( status ) ) { #ifdef UNICODE_STRINGS length /= sizeof( wchar_t ); #endif /* UNICODE_STRINGS */ name[ length ] = TEXT( '\0' ); status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name ); } if( cryptStatusError( status ) ) return( extErrorExit( cryptKeyset, "cryptDeleteKey()", status, __LINE__ ) ); status = cryptAddPublicKey( cryptKeyset, cryptCert ); } if( cryptStatusError( status ) ) { return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ ) ); } cryptDestroyCert( cryptCert ); /* Now try the same thing with a CRL. This code also tests the duplicate-detection mechanism, if we don't get a duplicate error there's a problem */ puts( "Adding CRL." ); status = importCertFromTemplate( &cryptCert, CRL_FILE_TEMPLATE, 1 ); if( cryptStatusError( status ) ) { printf( "Couldn't read CRL from file, status %d, line %d.\n", status, __LINE__ ); return( TRUE ); } status = cryptAddPublicKey( cryptKeyset, cryptCert ); if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE ) return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ ) ); status = cryptAddPublicKey( cryptKeyset, cryptCert ); if( status != CRYPT_ERROR_DUPLICATE ) { printf( "Addition of duplicate item to keyset failed to produce " "CRYPT_ERROR_DUPLICATE, status %d, line %d.\n", status, __LINE__ ); return( FALSE ); } cryptDestroyCert( cryptCert ); /* Finally, try it with a certificate chain */ puts( "Adding certificate chain." ); filenameParamFromTemplate( filenameBuffer, CERTCHAIN_FILE_TEMPLATE, CERT_CHAIN_NO ); status = importCertFile( &cryptCert, filenameBuffer ); if( cryptStatusError( status ) ) { printf( "Couldn't read certificate chain from file, status %d, " "line %d.\n", status, __LINE__ ); return( FALSE ); } status = cryptAddPublicKey( cryptKeyset, cryptCert ); if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE ) return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ ) ); cryptDestroyCert( cryptCert ); /* In addition to the other certs we also add the generic user certificate, which is used later in other tests. Since it may have been added earlier we try and delete it first (we can't use the existing version since the issuerAndSerialNumber won't match the one in the private-key keyset) */ status = getPublicKey( &cryptCert, USER_PRIVKEY_FILE, USER_PRIVKEY_LABEL ); if( cryptStatusError( status ) ) { printf( "Couldn't read user certificate from file, status %d, line " "%d.\n", status, __LINE__ ); return( FALSE ); } status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_COMMONNAME, name, &length ); if( cryptStatusError( status ) ) return( FALSE ); #ifdef UNICODE_STRINGS length /= sizeof( wchar_t ); #endif /* UNICODE_STRINGS */ name[ length ] = TEXT( '\0' ); do status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name ); while( cryptStatusOK( status ) ); status = cryptAddPublicKey( cryptKeyset, cryptCert ); if( status == CRYPT_ERROR_NOTFOUND ) { /* This can occur if a database keyset is defined but hasn't been initialised yet so the necessary tables don't exist, it can be opened but an attempt to add a key will return a not found error since it's the table itself rather than any item within it that isn't being found */ status = CRYPT_OK; } if( cryptStatusError( status ) ) return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ ) ); cryptDestroyCert( cryptCert ); /* Finally, if ECC is enabled we also add ECC certificates that are used later in other tests */ if( cryptStatusOK( cryptQueryCapability( CRYPT_ALGO_ECDSA, NULL ) ) ) { #ifdef UNICODE_STRINGS wchar_t wcBuffer[ FILENAME_BUFFER_SIZE ]; #endif /* UNICODE_STRINGS */ void *fileNamePtr = filenameBuffer; /* Add the P256 certificate */ filenameFromTemplate( filenameBuffer, SERVER_ECPRIVKEY_FILE_TEMPLATE, 256 ); #ifdef UNICODE_STRINGS mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 ); fileNamePtr = wcBuffer; #endif /* UNICODE_STRINGS */ status = getPublicKey( &cryptCert, fileNamePtr, USER_PRIVKEY_LABEL ); if( cryptStatusError( status ) ) { printf( "Couldn't read user certificate from file, status %d, " "line %d.\n", status, __LINE__ ); return( FALSE ); } status = cryptAddPublicKey( cryptKeyset, cryptCert ); if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE ) return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ ) ); cryptDestroyCert( cryptCert ); /* Add the P384 certificate */ filenameFromTemplate( filenameBuffer, SERVER_ECPRIVKEY_FILE_TEMPLATE, 384 ); #ifdef UNICODE_STRINGS mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 ); fileNamePtr = wcBuffer; #endif /* UNICODE_STRINGS */ status = getPublicKey( &cryptCert, fileNamePtr, USER_PRIVKEY_LABEL ); if( cryptStatusError( status ) ) { printf( "Couldn't read user certificate from file, status %d, " "line %d.\n", status, __LINE__ ); return( FALSE ); } status = cryptAddPublicKey( cryptKeyset, cryptCert ); if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE ) return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ ) ); cryptDestroyCert( cryptCert ); } /* Make sure the deletion code works properly. This is an artifact of the way RDBMS' work, the delete query can execute successfully but not delete anything so we make sure the glue code correctly translates this into a CRYPT_DATA_NOTFOUND */ status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, TEXT( "Mr.Not Appearing in this Keyset" ) ); if( status != CRYPT_ERROR_NOTFOUND ) { puts( "Attempt to delete a nonexistant key reports success, the " "database backend glue\ncode needs to be fixed to handle this " "correctly." ); return( FALSE ); } /* Close the keyset */ status = cryptKeysetClose( cryptKeyset ); if( cryptStatusError( status ) ) { printf( "cryptKeysetClose() failed with error code %d, line %d.\n", status, __LINE__ ); } return( TRUE ); }
static int exec_cmpcli_init(int argc, char **argv) { CRYPT_SESSION session; CRYPT_CERTIFICATE cert, cacert, req; CRYPT_CONTEXT keypair; CRYPT_KEYSET privkeys; const char *cmd, *uid, *ipwd, *crtfilename, *cacrtfilename, *kpfilename; void *crtdata; int status, data_len; if (argc != 6) { fprintf(stderr, "cmpcli argv!=6\n"); return 1; } cmd = argv[0]; uid = argv[1]; ipwd = argv[2]; crtfilename=argv[3]; cacrtfilename=argv[4]; kpfilename = argv[5]; fprintf(stderr, "uid=\"%s\" ipwd=\"%s\"\n", uid, ipwd); #if 0 crtdata = read_full_file(crtfilename, &data_len); if (!crtdata) return 1; status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cert); WARN_AND_RETURN_IF(status); free(crtdata); #endif crtdata = read_full_file(cacrtfilename, &data_len); if (!crtdata) return 1; status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cacert); WARN_AND_RETURN_IF(status); free(crtdata); status = create_keypair(&keypair, DEFAULT_PRIVKEY_LABEL); WARN_AND_RETURN_IF(status); status = cryptKeysetOpen(&privkeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, kpfilename, CRYPT_KEYOPT_CREATE); WARN_AND_RETURN_IF(status); status = cryptAddPrivateKey(privkeys, keypair, DEFAULT_PASSWORD); WARN_AND_RETURN_IF(status); status = cryptCreateCert(&req, CRYPT_UNUSED, CRYPT_CERTTYPE_REQUEST_CERT); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(req, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, keypair); WARN_AND_RETURN_IF(status); status = cryptSignCert(req, keypair); WARN_AND_RETURN_IF(status); status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_CMP_REQUESTTYPE, CRYPT_REQUESTTYPE_INITIALIZATION); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_CACERTIFICATE, cacert); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_REQUEST, req); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(session, CRYPT_SESSINFO_USERNAME, uid, strlen(uid)); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(session, CRYPT_SESSINFO_PASSWORD, ipwd, strlen(ipwd)); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1); WARN_AND_RETURN_IF(status); status = cryptGetAttribute(session, CRYPT_SESSINFO_RESPONSE, &cert); WARN_AND_RETURN_IF(status); status = export_cert(cert, crtfilename); WARN_AND_RETURN_IF(status); status = cryptAddPublicKey(privkeys, cert); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(privkeys); WARN_AND_RETURN_IF(status); status = cryptDestroySession(session); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cacert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(req); WARN_AND_RETURN_IF(status); status = cryptDestroyContext(keypair); return 0; }
static int connectCertstoreServer( void ) { CRYPT_SESSION cryptSession; CRYPT_KEYSET cryptCertStore; int connectionActive, status; puts( "Testing HTTP certstore server session..." ); /* Create the HTTP certstore session */ status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, CRYPT_SESSION_CERTSTORE_SERVER ); if( status == CRYPT_ERROR_PARAM3 ) /* Certstore session access not available */ return( CRYPT_ERROR_NOTAVAIL ); if( cryptStatusError( status ) ) { printf( "cryptCreateSession() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } if( !setLocalConnect( cryptSession, 80 ) ) return( FALSE ); /* Add the certificate store that we'll be using to provide certs (it's actually just the generic database keyset and not the full certificate store, because this contains more test certs) */ status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED, DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME, CRYPT_KEYOPT_READONLY ); if( status == CRYPT_ERROR_PARAM3 ) { /* This type of keyset access isn't available, return a special error code to indicate that the test wasn't performed, but that this isn't a reason to abort processing */ puts( "SVR: No certificate store available, aborting HTTP certstore " "responder test.\n" ); cryptDestroySession( cryptSession ); return( CRYPT_ERROR_NOTAVAIL ); } if( cryptStatusOK( status ) ) { status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_KEYSET, cryptCertStore ); cryptKeysetClose( cryptCertStore ); } if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "SVR: cryptSetAttribute()", status, __LINE__ ) ); /* Activate the server */ status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE ); printConnectInfo( cryptSession ); if( cryptStatusError( status ) ) { printExtError( cryptSession, "SVR: Attempt to activate HTTP " "certstore server session", status, __LINE__ ); cryptDestroySession( cryptSession ); return( FALSE ); } /* Check whether the session connection is still open */ status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_CONNECTIONACTIVE, &connectionActive ); if( cryptStatusError( status ) || !connectionActive ) { printExtError( cryptSession, "SVR: Persistent connection has been " "closed, operation", status, __LINE__ ); return( FALSE ); } /* Activate the connection to handle two more requests */ status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE ); if( cryptStatusError( status ) ) { printExtError( cryptSession, "SVR: Attempt to perform second HTTP " "certstore server transaction", status, __LINE__ ); cryptDestroySession( cryptSession ); return( status ); } status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE ); if( cryptStatusError( status ) ) { printExtError( cryptSession, "SVR: Attempt to perform third HTTP " "certstore server transaction", status, __LINE__ ); cryptDestroySession( cryptSession ); return( status ); } /* Clean up */ status = cryptDestroySession( cryptSession ); if( cryptStatusError( status ) ) { printf( "cryptDestroySession() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } puts( "SVR: HTTP certstore server session succeeded.\n" ); return( TRUE ); }
main(int argc, char **argv){ int ret; /* Return code */ int i; /* Loop iterator */ int bytesCopied; /* Bytes output by cryptlib enc/dec ops */ int reqAttrib; /* Crypt required attributed */ CRYPT_ENVELOPE dataEnv; /* Envelope for enc/dec */ CRYPT_KEYSET keyset; /* GPG keyset */ CRYPT_CONTEXT symContext; /* Key context */ char *keyPtr; /* Pointer to key */ char label[100]; /* Private key label */ int labelLength; /* Length of label */ char passbuf[1024]; /* Buffer for GPG key passphrase */ struct termios ts, ots; /* Strutures for saving/modifying term attribs */ char *clrDataPtr; /* Pointer to clear text */ int clrDataSize; /* Size of clear text */ int clrDataFd; /* Pointer to clear text file */ char *encDataPtr; /* Pointer to encrypted data */ int encDataSize; /* Size of encrypted data */ int encDataFd; /* Pointer to encrypted text file */ struct stat encDataFileInfo; /* fstat return for encrypted data file */ struct passwd *userInfo; /* Password info for input user */ char *keyFile; /* GPG key ring file name */ uid_t ownerID = getuid(); struct passwd *owner_pws = getpwuid(ownerID); char* owner_pwname = owner_pws->pw_name;//get the user login name; char* owner_pwdir = owner_pws->pw_dir; char *fileKeyName; *fileKeyName = malloc(strlen(owner_pwname)+strlen(argv[2]+10)); strcpy(fileKeyName,argv[2]); strcat(fileKeyName,".enc."); strcat(fileKeyName,owner_pwname); strcat(fileKeyName,".key"); printf("%s\n",fileKeyName); char *outputFileKeyName = malloc(strlen(argv[1])+strlen(argv[2])+20); strcpy(outputFileKeyName,argv[2]); strcat(outputFileKeyName,".enc."); strcat(outputFileKeyName,argv[1]); strcat(outputFileKeyName,".key"); printf("%s\n",outputFileKeyName); /*============================================== Check Check Check Check Check Check ============================================== */ if (argc!=3) {printf("Wrong number of arguments\n");exit(1);} char *fileName = malloc(strlen(argv[2])+5); strcpy(fileName,argv[2]); strcat(fileName,".enc"); fileChecker(fileName); /*============================================= Open DATAFILE and get data ============================================= */ encDataFd=open(fileKeyName,O_RDONLY); if (encDataFd<=0){perror("open encData1");exit(encDataFd);} ret=fstat(encDataFd,&encDataFileInfo); if (ret!=0){perror("fstat encDataFd");exit(ret);} encDataSize=encDataFileInfo.st_size; encDataPtr=malloc(encDataFileInfo.st_size); if (encDataPtr==NULL){perror("malloc encData");exit(__LINE__);} ret=read(encDataFd,encDataPtr,encDataSize); if (ret!=encDataSize){perror("read encData");exit(ret);} close(encDataFd); /*============================================== Cryptlib initialization ============================================== */ //cryptInit(); //ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL); //checkCryptNormal(ret,"cryptAddRandom",__LINE__); /*================================================= Decrypt the key ================================================= */ keyFile=malloc( strlen(owner_pwdir ) + strlen("/.gnupg/secring.gpg") + 1); if (keyFile==NULL){perror("malloc");exit(__LINE__);} strcpy(keyFile,owner_pwdir); strcat(keyFile,"/.gnupg/secring.gpg"); printf("Getting secret key from <%s>\n",keyFile); //Decrypt key cryptInit(); ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL); checkCryptNormal(ret,"cryptAddRandom",__LINE__); ret=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyFile, CRYPT_KEYOPT_READONLY); free(keyFile); checkCryptNormal(ret,"cryptKeysetOpen",__LINE__); ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_AUTO); checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__); ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_KEYSET_DECRYPT, keyset); checkCryptNormal(ret,"cryptSetAttribute",__LINE__); ret=cryptPushData(dataEnv,encDataPtr,encDataSize,&bytesCopied); /* Expect non-zero return -- indicates need private key */ ret=cryptGetAttribute(dataEnv, CRYPT_ATTRIBUTE_CURRENT, &reqAttrib); if (reqAttrib != CRYPT_ENVINFO_PRIVATEKEY) {printf("Decrypt error\n");exit(ret);} ret=cryptGetAttributeString(dataEnv, CRYPT_ENVINFO_PRIVATEKEY_LABEL, label, &labelLength); label[labelLength]='\0'; checkCryptNormal(ret,"cryptGetAttributeString",__LINE__); /*=============================================== Get the passphrase =============================================== */ tcgetattr(STDIN_FILENO, &ts); ots = ts; ts.c_lflag &= ~ECHO; ts.c_lflag |= ECHONL; tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts); tcgetattr(STDIN_FILENO, &ts); if (ts.c_lflag & ECHO) { fprintf(stderr, "Failed to turn off echo\n"); tcsetattr(STDIN_FILENO, TCSANOW, &ots); exit(1); } printf("Enter password for <%s>: ",label); fflush(stdout); fgets(passbuf, 1024, stdin); tcsetattr(STDIN_FILENO, TCSANOW, &ots); ret=cryptSetAttributeString(dataEnv, CRYPT_ENVINFO_PASSWORD, passbuf, strlen(passbuf)-1); if (ret != CRYPT_OK) { if (ret=CRYPT_ERROR_WRONGKEY) { printf("Wrong Key\n"); exit(ret); }else{ printf("cryptSetAttributeString line %d returned <%d>\n",__LINE__,ret); exit(ret); } } ret=cryptFlushData(dataEnv); checkCryptNormal(ret,"cryptFlushData",__LINE__); clrDataSize=KEYSIZE; clrDataPtr=malloc(clrDataSize); if (clrDataPtr==NULL){perror("malloc");exit(__LINE__);} bzero(clrDataPtr,clrDataSize); ret=cryptPopData(dataEnv,clrDataPtr,clrDataSize,&bytesCopied); checkCryptNormal(ret,"cryptPopData",__LINE__); ret=cryptDestroyEnvelope(dataEnv); checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__); cryptKeysetClose(keyset); checkCryptNormal(ret,"cryptKeysetClose",__LINE__); printf("Bytes decrypted <%d>\n",bytesCopied); for (i=0;i<bytesCopied;i++){printf("%c",clrDataPtr[i]);} ret=cryptEnd(); checkCryptNormal(ret,"cryptEnd",__LINE__); /*==================================================== Part2 Encrypt the key with user's private key ==================================================== */ /*============================================== Cryptlib initialization ============================================== */ cryptInit(); ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL); checkCryptNormal(ret,"cryptAddRandom",__LINE__); /*==================================================== Get key file name ==================================================== */ keyFile=malloc( strlen(owner_pwdir ) + strlen("/.gnupg/pubring.gpg") + 1); if (keyFile==NULL){perror("malloc");exit(__LINE__);} strcpy(keyFile,owner_pwdir); strcat(keyFile,"/.gnupg/pubring.gpg"); printf("Getting secret key from <%s>\n",keyFile); /*==================================================== Encrypt key with GPG public key Email address is for recipient =================================================== */ ret=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyFile, CRYPT_KEYOPT_READONLY); free(keyFile); checkCryptNormal(ret,"cryptKeysetOpen",__LINE__); ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_PGP); checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__); ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_KEYSET_ENCRYPT, keyset); checkCryptNormal(ret,"cryptSetAttribute",__LINE__); ret=cryptSetAttributeString(dataEnv, CRYPT_ENVINFO_RECIPIENT, argv[1],strlen(argv[1])); checkCryptNormal(ret,"cryptSetAttributeString",__LINE__); ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_DATASIZE, KEYSIZE); ret=cryptPushData(dataEnv,clrDataPtr,KEYSIZE,&bytesCopied); checkCryptNormal(ret,"cryptPushData",__LINE__); ret=cryptFlushData(dataEnv); checkCryptNormal(ret,"cryptFlushData",__LINE__); encDataSize=strlen(clrDataPtr)+1+1028; encDataPtr=malloc(encDataSize); if (encDataPtr==NULL){perror("malloc");exit(__LINE__);} ret=cryptPopData(dataEnv,encDataPtr,encDataSize,&bytesCopied); printf("cryptPopData returned <%d> bytes of encrypted data\n",bytesCopied); encDataSize=bytesCopied; ret=cryptDestroyEnvelope(dataEnv); checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__); cryptKeysetClose(keyset); checkCryptNormal(ret,"cryptKeysetClose",__LINE__); /*============================================== write it to output file. ============================================== */ printf("%s\n",outputFileKeyName); encDataFd=open(outputFileKeyName,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR); if (encDataFd<=0){perror("open encDataFd");exit(encDataFd);} ret=write(encDataFd,encDataPtr,bytesCopied); if (ret!=bytesCopied){perror("write encData");exit(ret);} close(encDataFd); int chmodStat = chmod (outputFileKeyName, S_IWRITE| S_IREAD| S_IRGRP | S_IWGRP); if(chmodStat<0){ perror("failed to chmod"); exit(-1); } free(encDataPtr); }
static void updateConfig( void ) { #if 0 const char *driverPath = "acospkcs11.dll"; /* ACOS */ const char *driverPath = "aetpkss1.dll"; /* AET */ const char *driverPath = "aloaha_pkcs11.dll"; /* Aloaha */ const char *driverPath = "etpkcs11.dll"; /* Aladdin eToken */ const char *driverPath = "psepkcs11.dll"; /* A-Sign */ const char *driverPath = "asepkcs.dll"; /* Athena */ const char *driverPath = "c:/temp/bpkcs11.dll"; /* Bloomberg */ const char *driverPath = "cryst32.dll"; /* Chrysalis */ const char *driverPath = "c:/program files/luna/cryst201.dll"; /* Chrysalis */ const char *driverPath = "pkcs201n.dll"; /* Datakey */ const char *driverPath = "dkck201.dll"; /* Datakey (for Entrust) */ const char *driverPath = "dkck232.dll"; /* Datakey/iKey (NB: buggy, use 201) */ const char *driverPath = "c:/program files/eracom/cprov sw/cryptoki.dll"; /* Eracom (old, OK) */ const char *driverPath = "c:/program files/eracom/cprov runtime/cryptoki.dll"; /* Eracom (new, doesn't work) */ const char *driverPath = "sadaptor.dll"; /* Eutron */ const char *driverPath = "ngp11v211.dll"; /* Feitian Technology */ const char *driverPath = "pk2priv.dll"; /* Gemplus */ const char *driverPath = "c:/program files/gemplus/gclib.dll"; /* Gemplus */ const char *driverPath = "cryptoki.dll"; /* IBM */ const char *driverPath = "csspkcs11.dll"; /* IBM */ const char *driverPath = "ibmpkcss.dll"; /* IBM */ const char *driverPath = "id2cbox.dll"; /* ID2 */ const char *driverPath = "cknfast.dll"; /* nCipher */ const char *driverPath = "/opt/nfast/toolkits/pkcs11/libcknfast.so";/* nCipher under Unix */ const char *driverPath = "/usr/lib/libcknfast.so"; /* nCipher under Unix */ const char *driverPath = "c:/program files/mozilla firefox/softokn3.dll";/* Netscape */ const char *driverPath = "nxpkcs11.dll"; /* Nexus */ const char *driverPath = "AuCryptoki2-0.dll"; /* Oberthur */ const char *driverPath = "opensc-pkcs11.dll"; /* OpenSC */ const char *driverPath = "micardoPKCS11.dll"; /* Orga Micardo */ const char *driverPath = "cryptoki22.dll"; /* Rainbow HSM (for USB use Datakey dvr) */ const char *driverPath = "p11card.dll"; /* Safelayer HSM (for USB use Datakey dvr) */ const char *driverPath = "slbck.dll"; /* Schlumberger */ const char *driverPath = "SetTokI.dll"; /* SeTec */ const char *driverPath = "siecap11.dll"; /* Siemens */ const char *driverPath = "smartp11.dll"; /* SmartTrust */ const char *driverPath = "SpyPK11.dll"; /* Spyrus */ #endif /* 0 */ const char *driverPath = "c:/program files/eracom/cprov sw/cryptoki.dll"; /* Eracom (old, OK) */ int status; printf( "Updating cryptlib configuration to load PKCS #11 driver\n " "'%s'\n as default driver...", driverPath ); /* Set the path for a PKCS #11 device driver. We only enable one of these at a time to speed the startup time */ status = cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_DEVICE_PKCS11_DVR01, driverPath, strlen( driverPath ) ); if( cryptStatusError( status ) ) { printf( "\n\nError updating PKCS #11 device driver profile, " "status %d.\n", status ); cleanupAndExit( EXIT_FAILURE ); } /* Flush the updated options to disk */ status = cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CONFIGCHANGED, FALSE ); if( cryptStatusError( status ) ) { printf( "\n\nError comitting device driver profile update to disk, " "status %d.\n", status ); cleanupAndExit( EXIT_FAILURE ); } puts( " done.\n" ); cleanupAndExit( EXIT_SUCCESS ); }
main(int argc, char **argv){ int i; /* Loop iterator */ int ret; /* Return value */ int total; /* Total key bytes */ int bytesCopied; /* Bytes output by cryptlib enc/dec ops */ int urandFd; /* Pointer to /dev/urandom */ char *keyPtr; /* Pointer to key */ CRYPT_ENVELOPE dataEnv; /* Envelope for encrypt/decrypt */ CRYPT_CONTEXT symContext; /* Key context */ char *clrDataPtr; /* Pointer to clear text */ int clrDataSize; /* Bytes of clear text */ int clrDataFd; /* Pointer to clear text file */ struct stat clrDataFileInfo; /* fstat return for clear text file */ int encDataFd; /* Pointer to encrypted text file */ char *encDataPtr; /* Pointer to encrypted data */ int encDataSize; /* Buffer bytes availble for decrypt */ struct stat encDataFileInfo; /* fstat return for encrypted data file */ if (argc!=3) {printf("Wrong number of arguments\n");exit(__LINE__);} /*============================================== Cryptlib initialization ============================================== */ cryptInit(); ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL); checkCryptNormal(ret,"cryptAddRandom",__LINE__); /*============================================= Open DATAFILE and get data ============================================= */ clrDataFd=open(argv[1],O_RDONLY); if (clrDataFd<=0){perror("open clrData");exit(clrDataFd);} ret=fstat(clrDataFd,&clrDataFileInfo); if (ret!=0){perror("fstat clrDataFd");exit(ret);} clrDataSize=clrDataFileInfo.st_size; clrDataPtr=malloc(clrDataFileInfo.st_size); if (clrDataPtr==NULL){perror("malloc clrData");exit(__LINE__);} ret=read(clrDataFd,clrDataPtr,clrDataSize); if (ret!=clrDataSize){perror("read clrData");exit(ret);} close(clrDataFd); /*============================================== (1) Generate the key ============================================== */ keyPtr=malloc(KEYSIZE); if (keyPtr==NULL){perror("malloc keyPtr");exit(__LINE__);} urandFd=open("/dev/urandom",O_RDONLY); if (urandFd<=0){perror("open urandFd");exit(urandFd);} total=0;ret=0; while (total<KEYSIZE){ ret=read(urandFd,&keyPtr[total],KEYSIZE-total);total+=ret; if (ret < 0){perror("read urand");exit(ret);} } close(urandFd); /*============================================== (2) Encrypt data from file with the key and write it to output file. ============================================== */ ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_CRYPTLIB); checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__); ret=cryptCreateContext(&symContext, CRYPT_UNUSED, SYMMETRIC_ALG); checkCryptNormal(ret,"cryptCreateContext",__LINE__); ret=cryptSetAttributeString(symContext, CRYPT_CTXINFO_KEY,keyPtr,KEYSIZE); checkCryptNormal(ret,"cryptSetAttributeString",__LINE__); ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_SESSIONKEY, symContext); checkCryptNormal(ret,"cryptSetAttribute",__LINE__); ret=cryptDestroyContext(symContext); checkCryptNormal(ret,"cryptDestroyContext",__LINE__); ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_DATASIZE, clrDataSize); checkCryptNormal(ret,"cryptSetAttribute",__LINE__); ret=cryptPushData(dataEnv,clrDataPtr,clrDataSize,&bytesCopied); checkCryptNormal(ret,"cryptAddRandom",__LINE__); cryptFlushData(dataEnv); encDataSize=clrDataFileInfo.st_size+2048; encDataPtr=malloc(encDataSize); if (encDataPtr==NULL){perror("malloc encData");exit(__LINE__);} ret=cryptPopData(dataEnv,encDataPtr,encDataSize,&bytesCopied); checkCryptNormal(ret,"cryptPopData",__LINE__); printf("<%d> bytes of encrypted data\n",bytesCopied); ret=cryptDestroyEnvelope(dataEnv); checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__); encDataFd=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR); if (encDataFd<=0){perror("open encDataFd");exit(encDataFd);} ret=write(encDataFd,encDataPtr,bytesCopied); if (ret!=bytesCopied){perror("write encData");exit(ret);} close(encDataFd); free(encDataPtr); /*====================================================== Get decrypted data from file and write to stdout ====================================================== */ encDataFd=open(argv[2],O_RDONLY); if (encDataFd<=0){perror("(2) open encDataFd");exit(encDataFd);} ret=fstat(encDataFd,&encDataFileInfo); if (ret!=0){perror("fstat encDataFd");exit(ret);} encDataSize=encDataFileInfo.st_size; encDataPtr=malloc(encDataSize); if (encDataPtr==NULL){perror("malloc encData");exit(__LINE__);} ret=read(encDataFd,encDataPtr,encDataSize); if (ret!=encDataSize){perror("read encData");exit(ret);} close(encDataFd); cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_AUTO); checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__); cryptPushData(dataEnv,encDataPtr,encDataSize,&bytesCopied); checkCryptNormal(ret,"cryptPushData",__LINE__); cryptCreateContext(&symContext,CRYPT_UNUSED,SYMMETRIC_ALG); checkCryptNormal(ret,"cryptCreateContext",__LINE__); cryptSetAttributeString(symContext, CRYPT_CTXINFO_KEY,keyPtr,KEYSIZE); checkCryptNormal(ret,"cryptSetAttributeString",__LINE__); cryptSetAttribute(dataEnv,CRYPT_ENVINFO_SESSIONKEY,symContext); checkCryptNormal(ret,"cryptSetAttribute",__LINE__); ret=cryptDestroyContext(symContext); checkCryptNormal(ret,"cryptDestroyContext",__LINE__); cryptFlushData(dataEnv); ret=cryptPopData(dataEnv,clrDataPtr,clrDataSize,&bytesCopied); checkCryptNormal(ret,"cryptPopData",__LINE__); ret=cryptDestroyEnvelope(dataEnv); checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__); printf("<%d> bytes of decrypted data\n",bytesCopied); for (i=0;i<bytesCopied;i++){printf("%c",clrDataPtr[i]);} printf("\n"); fflush(stdout); ret=cryptEnd(); checkCryptNormal(ret,"cryptEnd",__LINE__); }
static int exec_cmpcli_revoke(int argc, char **argv) { CRYPT_SESSION session; CRYPT_CONTEXT privkey; CRYPT_KEYSET privkeys; CRYPT_CERTIFICATE cert, cacert, revreq; const char *cmd, *crtfilename, *cacrtfilename, *kpfilename; void *crtdata; int status, data_len; if (argc != 4) { fprintf(stderr, "cmpcli revoke argv!=4\n"); return 1; } cmd = argv[0]; crtfilename=argv[1]; cacrtfilename=argv[2]; kpfilename = argv[3]; if (strcmp(cmd, "revoke") != 0) { fprintf(stderr, "cmpcli knows revoke only\n"); return 1; } crtdata = read_full_file(crtfilename, &data_len); if (!crtdata) return 1; status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cert); WARN_AND_RETURN_IF(status); free(crtdata); crtdata = read_full_file(cacrtfilename, &data_len); if (!crtdata) return 1; status = cryptImportCert(crtdata, data_len, CRYPT_UNUSED, &cacert); WARN_AND_RETURN_IF(status); free(crtdata); status = cryptKeysetOpen(&privkeys, CRYPT_UNUSED, CRYPT_KEYSET_FILE, kpfilename, CRYPT_KEYOPT_NONE); WARN_AND_RETURN_IF(status); status = cryptGetPrivateKey(privkeys, &privkey, CRYPT_KEYID_NAME, DEFAULT_PRIVKEY_LABEL, DEFAULT_PASSWORD); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(privkeys); WARN_AND_RETURN_IF(status); status = cryptCreateCert(&revreq, CRYPT_UNUSED, CRYPT_CERTTYPE_REQUEST_REVOCATION); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(revreq, CRYPT_CERTINFO_CERTIFICATE, cert); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(revreq, CRYPT_CERTINFO_CRLREASON, CRYPT_CRLREASON_AFFILIATIONCHANGED); WARN_AND_RETURN_IF(status); #if 0 status = cryptSignCert(revreq, privkey); WARN_AND_RETURN_IF(status); #endif status = cryptCreateSession(&session, CRYPT_UNUSED, CRYPT_SESSION_CMP); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_CMP_REQUESTTYPE, CRYPT_REQUESTTYPE_REVOCATION); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_PRIVATEKEY, privkey); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_REQUEST, revreq); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_CACERTIFICATE, cacert); WARN_AND_RETURN_IF(status); #if 0 status = cryptSetAttributeString(session, CRYPT_SESSINFO_USERNAME, uid, strlen(uid)); WARN_AND_RETURN_IF(status); status = cryptSetAttributeString(session, CRYPT_SESSINFO_PASSWORD, rpwd, strlen(rpwd)); WARN_AND_RETURN_IF(status); #endif status = cryptSetAttributeString(session, CRYPT_SESSINFO_SERVER_NAME, "127.0.0.1", 9); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_SERVER_PORT, 65000); WARN_AND_RETURN_IF(status); status = cryptSetAttribute(session, CRYPT_SESSINFO_ACTIVE, 1); if (!cryptStatusOK(status)) { CRYPT_ERRTYPE_TYPE errtype; CRYPT_ATTRIBUTE_TYPE locus; char *errstring; int errstringlen; cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype); cryptGetAttribute(session, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus); fprintf(stderr, "session errtype %d locus %d\n", errtype, locus); cryptGetAttribute(revreq, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype); cryptGetAttribute(revreq, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus); fprintf(stderr, "revreq errtype %d locus %d\n", errtype, locus); cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype); cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus); fprintf(stderr, "cert errtype %d locus %d\n", errtype, locus); cryptGetAttribute(cacert, CRYPT_ATTRIBUTE_ERRORTYPE, (int *)&errtype); cryptGetAttribute(cacert, CRYPT_ATTRIBUTE_ERRORLOCUS, (int *)&locus); fprintf(stderr, "cacert errtype %d locus %d\n", errtype, locus); cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, NULL, &errstringlen); errstring = malloc(errstringlen + 10); cryptGetAttributeString(session, CRYPT_ATTRIBUTE_ERRORMESSAGE, errstring, &errstringlen); errstring[errstringlen] = 0; fprintf(stderr, "session errmsg: %s\n", errstring); free(errstring); } WARN_AND_RETURN_IF(status); status = cryptDestroyContext(privkey); WARN_AND_RETURN_IF(status); status = cryptDestroySession(session); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cacert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(revreq); WARN_AND_RETURN_IF(status); return 0; }
static int fuzzSession( const CRYPT_SESSION_TYPE sessionType ) { CRYPT_SESSION cryptSession; const BOOLEAN isServer = \ ( sessionType == CRYPT_SESSION_SSH_SERVER || \ sessionType == CRYPT_SESSION_SSL_SERVER || \ sessionType == CRYPT_SESSION_OCSP_SERVER || \ sessionType == CRYPT_SESSION_TSP_SERVER || \ sessionType == CRYPT_SESSION_CMP_SERVER || \ sessionType == CRYPT_SESSION_SCEP_SERVER ) ? \ TRUE : FALSE; int status; /* Create the session */ status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType ); if( cryptStatusError( status ) ) return( status ); /* Set up the various attributes needed to establish a minimal session */ if( !isServer ) { status = cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_SERVER_NAME, "www.example.com", 15 ); if( cryptStatusError( status ) ) return( status ); } if( isServer ) { CRYPT_CONTEXT cryptPrivKey; char filenameBuffer[ FILENAME_BUFFER_SIZE ]; filenameFromTemplate( filenameBuffer, SERVER_PRIVKEY_FILE_TEMPLATE, 1 ); status = getPrivateKey( &cryptPrivKey, filenameBuffer, USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD ); if( cryptStatusOK( status ) ) { status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_PRIVATEKEY, cryptPrivKey ); cryptDestroyContext( cryptPrivKey ); } if( cryptStatusError( status ) ) return( status ); } if( sessionType == CRYPT_SESSION_SSH || \ sessionType == CRYPT_SESSION_SSH_SERVER ) { status = cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_USERNAME, SSH_USER_NAME, paramStrlen( SSH_USER_NAME ) ); if( cryptStatusOK( status ) ) { status = cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_PASSWORD, SSH_PASSWORD, paramStrlen( SSH_PASSWORD ) ); } if( cryptStatusError( status ) ) return( status ); } status = cryptSetFuzzData( cryptSession, NULL, 0 ); cryptDestroySession( cryptSession ); return( CRYPT_OK ); }
static int testTSP( const CRYPT_SESSION cryptSession, const BOOLEAN isServer, const BOOLEAN isRecycledConnection, const BOOLEAN useAltHash, const BOOLEAN localSession ) { int status; /* If we're the client, wait for the server to finish initialising */ if( localSession && !isServer && waitMutex() == CRYPT_ERROR_TIMEOUT ) { printf( "Timed out waiting for server to initialise, line %d.\n", __LINE__ ); return( FALSE ); } /* If we're the client, create a message imprint to timestamp */ if( !isServer ) { CRYPT_CONTEXT hashContext; /* Create the hash value to add to the TSP request */ status = cryptCreateContext( &hashContext, CRYPT_UNUSED, useAltHash ? CRYPT_ALGO_SHA256 : \ CRYPT_ALGO_SHA1 ); if( cryptStatusError( status ) ) return( FALSE ); cryptEncrypt( hashContext, "12345678", 8 ); cryptEncrypt( hashContext, "", 0 ); if( isRecycledConnection ) { /* If we're moving further data over an existing connection, delete the message imprint from the previous run */ status = cryptDeleteAttribute( cryptSession, CRYPT_SESSINFO_TSP_MSGIMPRINT ); if( cryptStatusError( status ) ) { printf( "cryptDeleteAttribute() failed with error code %d, " "line %d.\n", status, __LINE__ ); return( FALSE ); } } status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_TSP_MSGIMPRINT, hashContext ); if( cryptStatusError( status ) ) { printf( "cryptSetAttribute() failed with error code %d, line " "%d.\n", status, __LINE__ ); return( FALSE ); } cryptDestroyContext( hashContext ); /* If it's a local session, wait for the server to finish initialising */ if( localSession && waitMutex() == CRYPT_ERROR_TIMEOUT ) { printf( "Timed out waiting for server to initialise, line %d.\n", __LINE__ ); return( FALSE ); } } else { /* We're the server, if this is the first connect tell the client that we're ready to go */ if( localSession && !isRecycledConnection ) releaseMutex(); } /* Activate the session and timestamp the message */ #if TSP_SERVER_NO == 11 cryptSetAttribute( cryptSession, CRYPT_OPTION_NET_READTIMEOUT, 30 ); #endif /* Very slow TSP */ status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE ); if( isServer ) printConnectInfo( cryptSession ); if( cryptStatusError( status ) ) { printExtError( cryptSession, isServer ? \ "SVR: Attempt to activate TSP server session" : \ "Attempt to activate TSP client session", status, __LINE__ ); if( !isServer && isServerDown( cryptSession, status ) ) { puts( " (Server could be down, faking it and continuing...)\n" ); cryptDestroySession( cryptSession ); return( CRYPT_ERROR_FAILED ); } cryptDestroySession( cryptSession ); return( FALSE ); } /* There's not much more we can do in the client at this point since the TSP data is only used internally by cryptlib, OTOH if we get to here then we've received a valid response from the TSA so all is OK */ if( !isServer ) { CRYPT_ENVELOPE cryptEnvelope; BYTE buffer[ BUFFER_SIZE ]; int bytesCopied; status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE, &cryptEnvelope ); if( cryptStatusError( status ) ) { printExtError( cryptSession, "Attempt to process returned " "timestamp", status, __LINE__ ); return( FALSE ); } status = cryptPopData( cryptEnvelope, buffer, BUFFER_SIZE, &bytesCopied ); if( cryptStatusError( status ) ) { printf( "cryptPopData() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } printf( "Timestamp data size = %d bytes.\n", bytesCopied ); debugDump( "tstinfo", buffer, bytesCopied ); cryptDestroyEnvelope( cryptEnvelope ); } return( TRUE ); }
int funcion3() { int tam, tam2, tamRelleno, status, keySize, valido, i, tamCert, keyMaxSize; long int opcion_l2, opcion_l; char opcion[5], *claveEncrypt, *buffer, *ptr, *endptr, *rutaToEncrypt, *directorio, *rutaSim, *nombreSim, *rutaEncrypted, *cabecera1, *cabecera2, *varlocal, *varlocal2, *password, *rutaKeyset, *nombreKeyset, *busSim, *bytesRelleno, *bufferCert, *claveExportada; FILE *ptrEncrypt, *ptrSim, *ptrEncrypted, *ptrCert; DIR *dir; struct stat st; struct dirent *ent; CRYPT_CERTIFICATE certificado; /*Reservo memoria*/ nombreKeyset=(char *)malloc(50); rutaKeyset=(char *)malloc(120); password=(char *)malloc(20); rutaToEncrypt=(char *)malloc(120); directorio=(char *)malloc(120); rutaSim=(char *)malloc(120); busSim=(char *)malloc(5); nombreSim=(char *)malloc(50); rutaEncrypted=(char *)malloc(120); varlocal=(char *)malloc(3); varlocal2=(char *)malloc(3); cabecera1=(char *)malloc(3); cabecera2=(char *)malloc(3); bytesRelleno=(char *)malloc(2); system("clear"); printf("\n ------------------------------------\n"); printf("| Cifrar un archivo |\n"); printf(" ------------------------------------\n\n"); fflush(stdout); /*PASO 1. Ruta del archivo a cifrar*/ do { valido=0; printf("PASO 1. Introduzca la ruta del archivo que desea cifrar: "); scanf("%s", rutaToEncrypt); if((ptrEncrypt=fopen(rutaToEncrypt, "rb")) == NULL ) { printf("No se encuentra el archivo. Revise la ruta :)\n\n"); valido=1; fflush(stdout); } } while(valido==1); /*Buscamos el caracter '/' dentro de la cadena. Si está, es porque el usuario metió la ruta completa*/ if((ptr=(strrchr(rutaToEncrypt, '/')))!=NULL) sprintf(rutaEncrypted, "./Archivos encriptados/%s.enc", ptr+1); //Ruta completa else sprintf(rutaEncrypted, "./Archivos encriptados/%s.enc", rutaToEncrypt); //El usuario metió el nombre del archivo /*PASO 2. Algoritmo de cifrado*/ do { valido=0; printf("\nPASO 2. Seleccione el algoritmo de cifrado que desea utilizar:\n"); printf(" 1. AES (por defecto)\n"); printf(" 2. DES\n"); printf(" 3. RSA\n"); fflush(stdout); printf("Opción (Introduzca 0 para la opción por defecto) >> "); scanf ("%s", &opcion); /*Comprobacion de la validez de la selección (que sea un número) (usando strtol, si hay algun caracter no numérico, endptr apunta al primero de ellos, lo cual implica que si la cadena apuntada por endptr no tiene longitud 0 es porque se ha introducido un caracter no numérico)*/ opcion_l = strtol(opcion,&endptr,10); if(strlen(endptr)!=0 || opcion_l < 0 || opcion_l > 3) { printf("Ops... tendrás que meter un número entre 1 y 3 la próxima vez ;) Try again!\n"); fflush(stdout); valido=1; } } while(valido==1); /*Distinto tratamiento según el cifrado escogido*/ CRYPT_CONTEXT contextoEncrypt, contextoPrivado; if(opcion_l==1 || opcion_l==0) { //AES /*Vamos a comprobar que tam sea multiplo del tamaño de bloque*/ stat(rutaToEncrypt, &st); tam2=st.st_size; if(tam2%16!=0) { tam=(int)tam2/16; tam++; tam=tam*16; tamRelleno=tam-tam2; } else { tamRelleno=0; tam=tam2; } /*Creamos contextos..*/ if((status=cryptCreateContext(&contextoEncrypt, CRYPT_UNUSED, CRYPT_ALGO_AES))!=CRYPT_OK) { printf("Error al crear el contexto AES. Código %d\n", status); fflush(stdout); return(-1); } else if((status=cryptSetAttributeString(contextoEncrypt, CRYPT_CTXINFO_IV, "1234567891123456", 16))!=CRYPT_OK) { printf("Error con el vector de inicialización. Código %d\n", status); fflush(stdout); return(-1); } do { //Seleccionamos el tamaño de clave en AES valido=0; printf("\nPASO 3. Seleccione el tamaño de clave:\n"); printf(" 1. 128 bits (por defecto)\n"); printf(" 2. 192 bits\n"); printf(" 3. 256 bits\n"); fflush(stdout); printf("Opción (Introduzca 0 para la opción por defecto)>> "); scanf ("%s", &opcion); /*Comprobacion de la validez de la selección (que sea un número) (usando strtol, si hay algun caracter no numérico, endptr apunta al primero de ellos, lo cual implica que si la cadena apuntada por endptr no tiene longitud 0 es porque se ha introducido un caracter no numérico)*/ opcion_l2 = strtol(opcion,&endptr,10); if(strlen(endptr)!=0 || opcion_l2 < 0 || opcion_l2 > 3) { printf("Ops... tendrás que meter un número entre 1 y 3 la próxima vez ;) Try again!\n"); fflush(stdout); valido=1; } } while(valido==1); if(opcion_l2==2) { if((status=cryptSetAttribute(contextoEncrypt, CRYPT_CTXINFO_KEYSIZE, 192/8))!=CRYPT_OK) { //192 bits printf("Error al asignar tamaño de clave. Código %d\n", status); fflush(stdout); return(-1); } } else if(opcion_l2==3) { if((status=cryptSetAttribute(contextoEncrypt, CRYPT_CTXINFO_KEYSIZE, 256/8))!=CRYPT_OK) { //256 bits printf("Error al asignar tamaño de clave. Código %d\n", status); fflush(stdout); return(-1); } } strcpy(busSim, ".aes"); /*Será la cabecera que incluiremos al principio del archivo encriptado*/ cabecera1=cesarEncrypt("aes", 17, varlocal);/*Ciframos "aes" con cifrado césar. Número de posiciones desplazadas: 17 */ } else if(opcion_l==2) { //DES /*Vamos a comprobar que tam sea multiplo del tamaño de bloque*/ stat(rutaToEncrypt, &st); tam2=st.st_size; if(tam2%16!=0) { tam=(int)tam2/16; tam++; tam=tam*16; tamRelleno=tam-tam2; } else { tamRelleno=0; tam=tam2; } if((status=cryptCreateContext(&contextoEncrypt, CRYPT_UNUSED, CRYPT_ALGO_DES))!=CRYPT_OK) { printf("Error al crear el contexto DES. Código %d\n", status); fflush(stdout); return(-1); } else if((status=cryptSetAttributeString(contextoEncrypt, CRYPT_CTXINFO_IV, "12345678", 8))!=CRYPT_OK) { printf("Error con el vector de inicialización. Código %d\n", status); fflush(stdout); return(-1); } strcpy(busSim, ".des"); /*Será la cabecera que incluiremos al principio del ptrEncrypt encriptado*/ cabecera1=cesarEncrypt("des", 17, varlocal);/*Ciframos "des" con cifrado césar. Número de posiciones desplazadas: 17 */ } else if(opcion_l==3) { //RSA stat(rutaToEncrypt, &st); tam2=st.st_size; if(tam2%128!=0) { tam=(int)tam2/128; tam++; tam=tam*128; } else { tam=tam2; } } if(opcion_l==0 || opcion_l==1) printf("\nPASO 4. Seleccione el modo de funcionamiento:\n"); if(opcion_l==2) printf("\nPASO 3. Seleccione el modo de funcionamiento:\n"); /*Modo de funcionamiento si se seleccionó cifrado simétrico*/ if(opcion_l!=3) { do { valido=0; printf(" 1. CBC (por defecto)\n"); printf(" 2. ECB\n"); fflush(stdout); printf("Opción (Introduzca 0 para la opción por defecto) >> "); scanf ("%s", &opcion); /*Comprobacion de la validez de la selección (que sea un número) (usando strtol, si hay algun caracter no numérico, endptr apunta al primero de ellos, lo cual implica que si la cadena apuntada por endptr no tiene longitud 0 es porque se ha introducido un caracter no numérico)*/ opcion_l2 = strtol(opcion,&endptr,10); if(strlen(endptr)!=0 || opcion_l2 < 0 || opcion_l2 > 2) { printf("Ops... tendrás que meter un número entre 1 y 2 la próxima vez ;) Try again!\n"); fflush(stdout); valido=1; } } while(valido==1); if(opcion_l2==1) { //CBC if((status=cryptSetAttribute(contextoEncrypt, CRYPT_CTXINFO_MODE, CRYPT_MODE_CBC))!=CRYPT_OK) { printf("Error al asignar modo de funcionamiento\n"); fflush(stdout); return(-1); } cabecera2=cesarEncrypt("cbc", 14, varlocal2); /*Ciframos "cbc" con cifrado césar. Número de posiciones desplazadas: 14 */ } else if(opcion_l2==2) { //ECB if((status=cryptSetAttribute(contextoEncrypt, CRYPT_CTXINFO_MODE, CRYPT_MODE_ECB))!=CRYPT_OK) { printf("Error al asignar modo de funcionamiento\n"); fflush(stdout); return(-1); } cabecera2=cesarEncrypt("ecb", 14, varlocal2); /*Ciframos "ecb" con cifrado césar. Número de posiciones desplazadas: 14 */ } /*Password*/ if(opcion_l==1 || opcion_l==0) printf("\nPASO 5. Introduzca una contraseña >> "); if(opcion_l==2) printf("\nPASO 4. Introduzca una contraseña >> "); fflush(stdout); do { valido=0; scanf("%s", password); if((strlen(password))<2) { printf("La contraseña debe tener más de un caracter\n"); fflush(stdout); valido=1; } }while(valido==1); /*Necesitamos la clave simétrica adecuada*/ dir = opendir ("./Claves y certificados/"); if (dir != NULL) { i=0; /* Nos va a mostrar los archivos que haya dentro de la carpeta Claves y cert. que correspondan*/ while ((ent = readdir (dir)) != NULL) { if((ptr=strstr(ent->d_name, busSim))!=NULL) { strcpy(nombreSim, ent->d_name); i++; } } closedir(dir); } else { /* Problemas al abrir el directorio */ printf("¿Ha ejecutado ya la opción 2?\n"); fflush(stdout); return(-1); } if(i==0) { printf("No se ha encontrado ninguna clave simétrica. (¿Ha ejecutado ya la opción 2?)\n"); fflush(stdout); return(-1); } else if(i==1) { printf("\n-> Se ha encontrado 1 clave simétrica. Se usará %s por defecto\n\n", nombreSim); fflush(stdout); sprintf(rutaSim, "./Claves y certificados/%s", nombreSim); } else { printf("\n¡¡ Hay %d claves simétricas creadas !!\n", i); fflush(stdout); i=0; dir = opendir ("./Claves y certificados/"); /* Nos va a mostrar los archivos que haya dentro de la carpeta Claves y cert. adecuados*/ while ((ent = readdir (dir)) != NULL) { if((ptr=strstr(ent->d_name, busSim))!=NULL) { i++; printf(" %d. %s\n", i, ent->d_name); } } closedir(dir); do{ valido=0; printf("Introduzca el número de la clave simétrica que desea usar >> "); scanf("%s", &opcion); opcion_l2 = strtol(opcion,&endptr,10); if(strlen(endptr)!=0 || opcion_l2 < 1 || opcion_l2 > i) { printf("Ops... tendrás que meter un número entre 1 y %d la próxima vez ;) Try again!\n", i); fflush(stdout); valido=1; } }while(valido==1); /*Guardamos el nombre del archivo correspondiente en rutaSim*/ dir = opendir ("./Claves y certificados/"); i=0; while ((ent = readdir (dir)) != NULL) { if((ptr=strstr(ent->d_name, busSim))!=NULL) { i++; if(opcion_l2==i) { sprintf(rutaSim, "./Claves y certificados/%s", ent->d_name); } } } closedir(dir); } /*Recuperamos la clave privada y la guardamos en el contextoPrivado ya que la necesitamos*/ /*Abrimos el keyset*/ dir = opendir ("./Claves y certificados/"); if (dir != NULL) { i=0; /* Nos va a mostrar los archivos .p15 que haya dentro de la carpeta Claves y cert.*/ while ((ent = readdir (dir)) != NULL) { if((ptr=strstr(ent->d_name, ".p15"))!=NULL) { strcpy(nombreKeyset, ent->d_name); i++; } } closedir(dir); } else { /* Problemas al abrir el directorio */ printf("¿Ha ejecutado ya la opción 1?\n"); fflush(stdout); return(-1); } if(i==0) { printf("\nNo se ha encontrado ningún archivo keyset. (¿Ha ejecutado ya la opción 1?)\n"); fflush(stdout); return(-1); } else if(i==1) { printf("\n-> Se ha encontrado 1 archivo keyset. Se usará %s por defecto\n\n", nombreKeyset); fflush(stdout); sprintf(rutaKeyset, "./Claves y certificados/%s", nombreKeyset); } else { printf("\n¡¡ Hay %d archivos keysets creados !!\n", i); i=0; dir = opendir ("./Claves y certificados/"); /* Nos va a mostrar los archivos .p15 que haya dentro de la carpeta Claves y cert.*/ while ((ent = readdir (dir)) != NULL) { if((ptr=strstr(ent->d_name, ".p15"))!=NULL) { i++; printf(" %d. %s\n", i, ent->d_name); } } closedir(dir); /*El usuario introduce el número que corresponde al archivo keyset que elija*/ do{ valido=0; printf("Introduzca el número del archivo keyset que desea usar >> "); scanf("%s", &opcion); opcion_l2 = strtol(opcion,&endptr,10); if(strlen(endptr)!=0 || opcion_l2 < 1 || opcion_l2 > i) { printf("Ops... tendrás que meter un número entre 1 y %d la próxima vez ;) Try again!\n", i); fflush(stdout); valido=1; } }while(valido==1); /*Guardamos el nombre del archivo correspondiente en rutaKeyset*/ dir = opendir ("./Claves y certificados/"); i=0; while ((ent = readdir (dir)) != NULL) { if((ptr=strstr(ent->d_name, ".p15"))!=NULL) { i++; if(opcion_l2==i) { sprintf(rutaKeyset, "./Claves y certificados/%s", ent->d_name); } } } closedir(dir); } /*Abrimos la clave simétrica elejida anteriormente por el usuario*/ if((ptrSim=fopen(rutaSim, "rb")) == NULL) { printf("Error al abrir la clave simétrica. (¿La ha creado ya?)\n"); fflush(stdout); return(-1); } stat(rutaSim, &st); keySize=st.st_size; claveEncrypt=(char *)malloc(keySize); status=fread(claveEncrypt, 1, keySize, ptrSim); /*Abrimos keyset, creamos contextos, importamos claves...*/ CRYPT_KEYSET keyset; if((status=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, rutaKeyset, CRYPT_KEYOPT_READONLY))!=CRYPT_OK) { printf("Error al abrir el archivo keyset. (¿Ha ejecutado la opción 1?). Código %d\n", status); fflush(stdout); return(-1); } if((status=cryptCreateContext(&contextoPrivado, CRYPT_UNUSED, CRYPT_ALGO_RSA))!=CRYPT_OK) { printf("Error al crear el contexto. Código %d\n", status); fflush(stdout); return(-1); } if((status=cryptGetPrivateKey(keyset, &contextoPrivado, CRYPT_KEYID_NAME, "claveRSA", password))!=CRYPT_OK) { printf("Error con la clave privada. (¿Es la misma contraseña que usó en la opción 1?). Código %d\n", status); fflush(stdout); return(-1); } if((status=cryptImportKey(claveEncrypt, keySize, contextoPrivado, contextoEncrypt))!=CRYPT_OK) { printf("Error al importar la clave. Asegúrese de que se usa el mismo algoritmo. Código %d\n", status); fflush(stdout); return(-1); } /*Encriptamos*/ buffer=(char *)malloc(tam); status=fread(buffer, 1, tam, ptrEncrypt); if((status=cryptEncrypt(contextoEncrypt, buffer, tam))!=CRYPT_OK) { printf("Error al encriptar %s. Código %d\n", rutaToEncrypt, status); fflush(stdout); return(-1); } } if(opcion_l==3) { if((ptrCert=fopen("./Claves y certificados/AES.cert", "rb")) == NULL ) { printf("Compruebe que haya generado ya una clave pública\n"); fflush(stdout); return(-1); } stat("./Claves y certificados/AES.cert", &st); tamCert=st.st_size; bufferCert=(char *)malloc(tamCert); status=fread(bufferCert, 1, tamCert, ptrCert); if((status=cryptImportCert(bufferCert, tamCert, CRYPT_UNUSED, &certificado))!=CRYPT_OK) { printf("Error al importar el certificado. Código %d\n", status); fflush(stdout); return(-1); } /*Encriptamos de 128 bytes en 128 bytes. Sin embargo, no podemos hacer cryptEncrypt para el mismo certificado/contexto. Pero lo dejamos asi ya que nos dara el error -21 esperado en la primera iteracion*/ tam2=tam/128; buffer=(char *)malloc(tam); for(i=0; i<tam2; i++) { status=fread(buffer, 1, 128, ptrEncrypt); if((status=cryptEncrypt(certificado, buffer, 128))!=CRYPT_OK) { printf("Error al cifrar el archivo %s. Código %d\n", rutaToEncrypt, status); fflush(stdout); return(-1); } *ptrEncrypt=*(ptrEncrypt+128); *buffer=*(buffer+128); } } /*Guardamos el archivo encriptado.*/ /*Compruebo que exista el directorio. Si lstat devuelve 0 es que existe. Si devuelve otro valor hay que crear el directorio*/ sprintf(directorio, "./Archivos encriptados"); if (status = lstat(directorio, &st) != 0) { if(status=mkdir(directorio, 0777) != 0) { printf("Error al crear el directorio\n"); fflush(stdout); return(-1); } } /*La ruta la hemos calculado al principio del todo, cuando el usuario metio la ruta del archivo*/ if((ptrEncrypted=fopen(rutaEncrypted, "wb")) == NULL) { printf("Error al crear el archivo\n"); fflush(stdout); return(-1); } /*Vamos a incluir una cabecera en el archivo para saber después los bytes de relleno que hemos añadido*/ sprintf(bytesRelleno, "%d", tamRelleno); if((status=fwrite(bytesRelleno, 1, 2, ptrEncrypted))!=2) { printf("Error al guardar el archivo\n"); fflush(stdout); return(-1); } /*Vamos a incluir una cabecera en el archivo para saber despues que tipo de cifrado se uso*/ *(cabecera1+3)='\0'; //Nos aseguramos que solo sean 3 bytes if((status=fwrite(cabecera1, 1, strlen(cabecera1), ptrEncrypted))!=strlen(cabecera1)) { printf("Error al guardar el archivo\n"); fflush(stdout); return(-1); } /*Vamos a incluir una cabecera en el archivo para saber después el modo de funcionamiento que se uso*/ *(cabecera2+3)='\0'; //Nos aseguramos que solo sean 3 bytes if((status=fwrite(cabecera2, 1, strlen(cabecera2), ptrEncrypted))!=strlen(cabecera2)) { printf("Error al guardar el archivo\n"); fflush(stdout); return(-1); } /*Guardamos los bytes del archivo encriptado en un archivo*/ if((status=fwrite(buffer, 1, tam, ptrEncrypted))!=tam) { printf("Error al guardar el archivo\n"); fflush(stdout); return(-1); } /*Cerramos descriptores y destruimos lo que sea necesario*/ fclose(ptrEncrypted); fclose(ptrSim); fclose(ptrEncrypt); //if((status=cryptKeysetClose(keyset))!=CRYPT_OK) { // printf("Error al cerrar el keyset. Código %d\n", status); // fflush(stdout); // return(-1); //} if((status=cryptDestroyContext(contextoPrivado))!=CRYPT_OK) { printf("Error al destruir el contexto. Código %d\n", status); fflush(stdout); return(-1); } if((status=cryptDestroyContext(contextoEncrypt))!=CRYPT_OK) { printf("Error al destruir el contexto. Código %d\n", status); fflush(stdout); return(-1); } return(0); }
static int connectRTCS( const CRYPT_SESSION_TYPE sessionType, const BOOLEAN multipleCerts, const BOOLEAN localSession ) { CRYPT_SESSION cryptSession; CRYPT_CERTIFICATE cryptRTCSRequest; char filenameBuffer[ FILENAME_BUFFER_SIZE ]; #ifdef UNICODE_STRINGS wchar_t wcBuffer[ FILENAME_BUFFER_SIZE ]; #endif /* UNICODE_STRINGS */ void *fileNamePtr = filenameBuffer; const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_RTCS_SERVER ) ? \ TRUE : FALSE; int status; printf( "%sTesting %sRTCS session...\n", isServer ? "SVR: " : "", localSession ? "local " : "" ); /* If we're the client, wait for the server to finish initialising */ if( localSession && !isServer && waitMutex() == CRYPT_ERROR_TIMEOUT ) { printf( "Timed out waiting for server to initialise, line %d.\n", __LINE__ ); return( FALSE ); } /* Create the RTCS session */ status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType ); if( status == CRYPT_ERROR_PARAM3 ) /* RTCS session access not available */ return( CRYPT_ERROR_NOTAVAIL ); if( cryptStatusError( status ) ) { printf( "cryptCreateSession() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } if( isServer ) { CRYPT_CONTEXT cryptPrivateKey; CRYPT_KEYSET cryptCertStore; if( !setLocalConnect( cryptSession, 80 ) ) return( FALSE ); /* Add the responder private key */ filenameFromTemplate( filenameBuffer, SERVER_PRIVKEY_FILE_TEMPLATE, 1 ); #ifdef UNICODE_STRINGS mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 ); fileNamePtr = wcBuffer; #endif /* UNICODE_STRINGS */ status = getPrivateKey( &cryptPrivateKey, fileNamePtr, USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD ); if( cryptStatusOK( status ) ) { status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_PRIVATEKEY, cryptPrivateKey ); cryptDestroyContext( cryptPrivateKey ); } if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "SVR: cryptSetAttribute()", status, __LINE__ ) ); /* Add the certificate store that we'll be using to provide revocation information */ status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED, DATABASE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME, CRYPT_KEYOPT_READONLY ); if( status == CRYPT_ERROR_PARAM3 ) { /* This type of keyset access isn't available, return a special error code to indicate that the test wasn't performed, but that this isn't a reason to abort processing */ puts( "SVR: No certificate store available, aborting RTCS " "responder test.\n" ); cryptDestroySession( cryptSession ); return( CRYPT_ERROR_NOTAVAIL ); } if( status == CRYPT_ERROR_OPEN ) { /* The keyset is available, but it hasn't been created yet by an earlier self-test, this isn't a reason to abort processing */ puts( "SVR: Certificate store hasn't been created yet by " "earlier tests, aborting\n RTCS responder test.\n" ); cryptDestroySession( cryptSession ); return( CRYPT_ERROR_NOTAVAIL ); } if( cryptStatusOK( status ) ) { status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_KEYSET, cryptCertStore ); cryptKeysetClose( cryptCertStore ); } if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "SVR: cryptSetAttribute()", status, __LINE__ ) ); /* Tell the client that we're ready to go */ if( localSession ) releaseMutex(); } else { CRYPT_KEYSET cryptKeyset; CRYPT_CERTIFICATE cryptCert = DUMMY_INIT; /* Get the certificate whose status we're checking */ status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, DATABASE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME, CRYPT_KEYOPT_READONLY ); if( cryptStatusOK( status ) ) { status = cryptGetPublicKey( cryptKeyset, &cryptCert, CRYPT_KEYID_NAME, TEXT( "Test user 1" ) ); cryptKeysetClose( cryptKeyset ); } if( cryptStatusError( status ) ) { printf( "Couldn't read certificate for RTCS status check, error " "code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } /* Create the RTCS request */ if( !initRTCS( &cryptRTCSRequest, cryptCert, localSession ? \ 1 : RTCS_SERVER_NO, multipleCerts ) ) return( FALSE ); cryptDestroyCert( cryptCert ); /* Set up the server information and activate the session. In theory the RTCS request will contain all the information needed for the session so there'd be nothing else to add before we activate it, however many certs contain incorrect server URLs so we set the server name manually if necessary, overriding the value present in the RTCS request (via the certificate) */ status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_REQUEST, cryptRTCSRequest ); if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "cryptSetAttribute()", status, __LINE__ ) ); cryptDestroyCert( cryptRTCSRequest ); if( localSession && !setLocalConnect( cryptSession, 80 ) ) return( FALSE ); #ifdef RTCS_SERVER_NAME if( !localSession ) { printf( "Setting RTCS server to %s.\n", RTCS_SERVER_NAME ); cryptDeleteAttribute( cryptSession, CRYPT_SESSINFO_SERVER_NAME ); status = cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_SERVER_NAME, RTCS_SERVER_NAME, paramStrlen( RTCS_SERVER_NAME ) ); if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "cryptSetAttributeString()", status, __LINE__ ) ); } #endif /* Kludges for incorrect/missing authorityInfoAccess values */ /* Wait for the server to finish initialising */ if( localSession && waitMutex() == CRYPT_ERROR_TIMEOUT ) { printf( "Timed out waiting for server to initialise, line %d.\n", __LINE__ ); return( FALSE ); } } status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE ); if( isServer ) printConnectInfo( cryptSession ); if( cryptStatusError( status ) ) { printExtError( cryptSession, isServer ? \ "SVR: Attempt to activate RTCS server session" : \ "Attempt to activate RTCS client session", status, __LINE__ ); if( !isServer && isServerDown( cryptSession, status ) ) { puts( " (Server could be down, faking it and continuing...)\n" ); cryptDestroySession( cryptSession ); return( CRYPT_ERROR_FAILED ); } cryptDestroySession( cryptSession ); return( FALSE ); } /* Obtain the response information */ if( !isServer ) { CRYPT_CERTIFICATE cryptRTCSResponse; status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE, &cryptRTCSResponse ); if( cryptStatusError( status ) ) { printf( "cryptGetAttribute() failed with error code %d, line " "%d.\n", status, __LINE__ ); return( FALSE ); } printCertInfo( cryptRTCSResponse ); cryptDestroyCert( cryptRTCSResponse ); } /* Clean up */ status = cryptDestroySession( cryptSession ); if( cryptStatusError( status ) ) { printf( "cryptDestroySession() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } puts( isServer ? "SVR: RTCS server session succeeded.\n" : \ "RTCS client session succeeded.\n" ); return( TRUE ); }
static int testKeysetRead( const CRYPT_KEYSET_TYPE keysetType, const C_STR keysetName, const CRYPT_KEYID_TYPE keyType, const C_STR keyName, const CRYPT_CERTTYPE_TYPE type, const int option ) { CRYPT_KEYSET cryptKeyset; CRYPT_CERTIFICATE cryptCert; BOOLEAN isCertChain = FALSE; int value, status; /* Open the keyset with a check to make sure this access method exists so we can return an appropriate error message */ status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, keysetType, keysetName, CRYPT_KEYOPT_READONLY ); if( status == CRYPT_ERROR_PARAM3 ) { /* This type of keyset access not available */ return( CRYPT_ERROR_NOTAVAIL ); } if( cryptStatusError( status ) ) { printf( "cryptKeysetOpen() failed with error code %d, line %d.\n", status, __LINE__ ); return( CRYPT_ERROR_FAILED ); } /* Read the certificate from the keyset */ status = cryptGetPublicKey( cryptKeyset, &cryptCert, keyType, keyName ); if( cryptStatusError( status ) ) { /* The access to network-accessible keysets can be rather temperamental and can fail at this point even though it's not a fatal error. The calling code knows this and will continue the self-test with an appropriate warning, so we explicitly clean up after ourselves to make sure we don't get a CRYPT_ORPHAN on shutdown */ if( keysetType == CRYPT_KEYSET_HTTP && \ status == CRYPT_ERROR_NOTFOUND ) { /* 404's are relatively common, and non-fatal */ extErrorExit( cryptKeyset, "cryptGetPublicKey()", status, __LINE__ ); puts( " (404 is a common HTTP error, and non-fatal)." ); return( TRUE ); } return( extErrorExit( cryptKeyset, "cryptGetPublicKey()", status, __LINE__ ) ); } /* Make sure that we got what we were expecting */ status = cryptGetAttribute( cryptCert, CRYPT_CERTINFO_CERTTYPE, &value ); if( cryptStatusError( status ) || ( value != type ) ) { printf( "Expecting certificate object type %d, got %d, line %d.", type, value, __LINE__ ); return( FALSE ); } if( value == CRYPT_CERTTYPE_CERTCHAIN ) isCertChain = TRUE; if( value == CRYPT_CERTTYPE_CERTCHAIN || value == CRYPT_CERTTYPE_CRL ) { value = 0; cryptSetAttribute( cryptCert, CRYPT_CERTINFO_CURRENT_CERTIFICATE, CRYPT_CURSOR_FIRST ); do value++; while( cryptSetAttribute( cryptCert, CRYPT_CERTINFO_CURRENT_CERTIFICATE, CRYPT_CURSOR_NEXT ) == CRYPT_OK ); printf( isCertChain ? "Certificate chain length = %d.\n" : \ "CRL has %d entries.\n", value ); } /* Check the certificate against the CRL. Any kind of error is a failure since the certificate isn't in the CRL */ if( keysetType != CRYPT_KEYSET_LDAP && \ keysetType != CRYPT_KEYSET_HTTP ) { if( !checkKeysetCRL( cryptKeyset, cryptCert, isCertChain ) ) return( FALSE ); } cryptDestroyCert( cryptCert ); /* If we're reading multiple certs using the same (cached) query type, try re-reading the certificate. This can't be easily tested from the outside because it's database back-end specific, so it'll require attaching a debugger to the read code to make sure that the cacheing is working as required */ if( option == READ_OPTION_MULTIPLE ) { int i; for( i = 0; i < 3; i++ ) { status = cryptGetPublicKey( cryptKeyset, &cryptCert, keyType, keyName ); if( cryptStatusError( status ) ) { printf( "cryptGetPublicKey() with cached query failed with " "error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } cryptDestroyCert( cryptCert ); } } /* Close the keyset */ status = cryptKeysetClose( cryptKeyset ); if( cryptStatusError( status ) ) { printf( "cryptKeysetClose() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } return( TRUE ); }
static int connectOCSP( const CRYPT_SESSION_TYPE sessionType, const BOOLEAN revokedCert, const BOOLEAN multipleCerts, const BOOLEAN localSession ) { CRYPT_SESSION cryptSession; CRYPT_CERTIFICATE cryptOCSPRequest; char filenameBuffer[ FILENAME_BUFFER_SIZE ]; #ifdef UNICODE_STRINGS wchar_t wcBuffer[ FILENAME_BUFFER_SIZE ]; #endif /* UNICODE_STRINGS */ void *fileNamePtr = filenameBuffer; #if OCSP_SERVER_NO == 7 int complianceValue; #endif /* OCSP servers that return broken resposnes */ const BOOLEAN isServer = ( sessionType == CRYPT_SESSION_OCSP_SERVER ) ? \ TRUE : FALSE; int status; printf( "%sTesting %sOCSP session...\n", isServer ? "SVR: " : "", localSession ? "local " : "" ); /* If we're the client, wait for the server to finish initialising */ if( localSession && !isServer && waitMutex() == CRYPT_ERROR_TIMEOUT ) { printf( "Timed out waiting for server to initialise, line %d.\n", __LINE__ ); return( FALSE ); } /* Create the OCSP session */ status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType ); if( status == CRYPT_ERROR_PARAM3 ) /* OCSP session access not available */ return( CRYPT_ERROR_NOTAVAIL ); if( cryptStatusError( status ) ) { printf( "cryptCreateSession() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } if( isServer ) { CRYPT_CONTEXT cryptPrivateKey; CRYPT_KEYSET cryptCertStore; if( !setLocalConnect( cryptSession, 80 ) ) return( FALSE ); /* Add the responder private key */ filenameFromTemplate( filenameBuffer, SERVER_PRIVKEY_FILE_TEMPLATE, 1 ); #ifdef UNICODE_STRINGS mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 ); fileNamePtr = wcBuffer; #endif /* UNICODE_STRINGS */ status = getPrivateKey( &cryptPrivateKey, fileNamePtr, USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD ); if( cryptStatusOK( status ) ) { status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_PRIVATEKEY, cryptPrivateKey ); cryptDestroyContext( cryptPrivateKey ); } if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "SVR: cryptSetAttribute()", status, __LINE__ ) ); /* Add the certificate store that we'll be using to provide revocation information */ status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED, DATABASE_KEYSET_TYPE, CERTSTORE_KEYSET_NAME, CRYPT_KEYOPT_READONLY ); if( status == CRYPT_ERROR_PARAM3 ) { /* This type of keyset access isn't available, return a special error code to indicate that the test wasn't performed, but that this isn't a reason to abort processing */ puts( "SVR: No certificate store available, aborting OCSP " "responder test.\n" ); cryptDestroySession( cryptSession ); return( CRYPT_ERROR_NOTAVAIL ); } if( cryptStatusOK( status ) ) { status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_KEYSET, cryptCertStore ); cryptKeysetClose( cryptCertStore ); } if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "SVR: cryptSetAttribute()", status, __LINE__ ) ); /* Tell the client that we're ready to go */ if( localSession ) releaseMutex(); } else { /* Create the OCSP request */ if( !initOCSP( &cryptOCSPRequest, localSession ? 1 : OCSP_SERVER_NO, FALSE, revokedCert, multipleCerts, CRYPT_SIGNATURELEVEL_NONE, CRYPT_UNUSED ) ) return( FALSE ); /* Set up the server information and activate the session. In theory the OCSP request will contain all the information needed for the session so there'd be nothing else to add before we activate it, however many certs contain incorrect server URLs so we set the server name manually if necessary, overriding the value present in the OCSP request (via the certificate) */ status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_REQUEST, cryptOCSPRequest ); if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "cryptSetAttribute()", status, __LINE__ ) ); cryptDestroyCert( cryptOCSPRequest ); if( localSession && !setLocalConnect( cryptSession, 80 ) ) return( FALSE ); #ifdef OCSP_SERVER_NAME if( !localSession ) { printf( "Setting OCSP server to %s.\n", OCSP_SERVER_NAME ); cryptDeleteAttribute( cryptSession, CRYPT_SESSINFO_SERVER_NAME ); status = cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_SERVER_NAME, OCSP_SERVER_NAME, paramStrlen( OCSP_SERVER_NAME ) ); if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "cryptSetAttributeString()", status, __LINE__ ) ); } #endif /* Kludges for incorrect/missing authorityInfoAccess values */ if( OCSP_SERVER_NO == 1 || localSession ) { /* The cryptlib server doesn't handle the weird v1 certIDs */ status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_VERSION, 2 ); if( cryptStatusError( status ) ) return( attrErrorExit( cryptSession, "cryptSetAttribute()", status, __LINE__ ) ); } #if OCSP_SERVER_NO == 7 /* Some OCSP server's responses are broken so we have to turn down the compliance level to allow them to be processed */ cryptGetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL, &complianceValue ); cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL, CRYPT_COMPLIANCELEVEL_OBLIVIOUS ); #endif /* OCSP servers that return broken resposnes */ /* Wait for the server to finish initialising */ if( localSession && waitMutex() == CRYPT_ERROR_TIMEOUT ) { printf( "Timed out waiting for server to initialise, line %d.\n", __LINE__ ); return( FALSE ); } } status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE ); #if OCSP_SERVER_NO == 7 /* Restore normal certificate processing */ cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL, complianceValue ); #endif /* OCSP servers that return broken resposnes */ if( isServer ) printConnectInfo( cryptSession ); if( cryptStatusError( status ) ) { printExtError( cryptSession, isServer ? \ "SVR: Attempt to activate OCSP server session" : \ "Attempt to activate OCSP client session", status, __LINE__ ); #if OCSP_SERVER_NO == 5 if( status == CRYPT_ERROR_SIGNATURE ) { char errorMessage[ 512 ]; int errorMessageLength; status = cryptGetAttributeString( cryptSession, CRYPT_ATTRIBUTE_ERRORMESSAGE, errorMessage, &errorMessageLength ); if( cryptStatusOK( status ) && errorMessageLength >= 29 && \ !memcmp( errorMessage, "OCSP response doesn't contain", 29 ) ) { cryptDestroySession( cryptSession ); puts( " (Verisign's OCSP responder sends broken responses, " "continuing...)\n" ); return( CRYPT_ERROR_FAILED ); } } #endif /* Verisign's broken OCSP responder */ if( !isServer && isServerDown( cryptSession, status ) ) { puts( " (Server could be down, faking it and continuing...)\n" ); cryptDestroySession( cryptSession ); return( CRYPT_ERROR_FAILED ); } cryptDestroySession( cryptSession ); return( FALSE ); } /* Obtain the response information */ if( !isServer ) { CRYPT_CERTIFICATE cryptOCSPResponse; status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_RESPONSE, &cryptOCSPResponse ); if( cryptStatusError( status ) ) { printf( "cryptGetAttribute() failed with error code %d, line " "%d.\n", status, __LINE__ ); return( FALSE ); } printCertInfo( cryptOCSPResponse ); cryptDestroyCert( cryptOCSPResponse ); } /* There are so many weird ways to delegate trust and signing authority mentioned in the OCSP RFC without any indication of which one implementors will follow that we can't really perform any sort of automated check since every responder seems to interpret this differently, and many require manual installation of responder certs in order to function */ #if 0 status = cryptCheckCert( cryptOCSPResponse , CRYPT_UNUSED ); if( cryptStatusError( status ) ) return( attrErrorExit( cryptOCSPResponse , "cryptCheckCert()", status, __LINE__ ) ); #endif /* 0 */ /* Clean up */ status = cryptDestroySession( cryptSession ); if( cryptStatusError( status ) ) { printf( "cryptDestroySession() failed with error code %d, line %d.\n", status, __LINE__ ); return( FALSE ); } puts( isServer ? "SVR: OCSP server session succeeded.\n" : \ "OCSP client session succeeded.\n" ); return( TRUE ); }
static int fuzzSession( const CRYPT_SESSION_TYPE sessionType, const char *fuzzFileName ) { CRYPT_SESSION cryptSession; CRYPT_CONTEXT cryptPrivKey = CRYPT_UNUSED; BYTE buffer[ 4096 ]; const BOOLEAN isServer = \ ( sessionType == CRYPT_SESSION_SSH_SERVER || \ sessionType == CRYPT_SESSION_SSL_SERVER || \ sessionType == CRYPT_SESSION_OCSP_SERVER || \ sessionType == CRYPT_SESSION_RTCS_SERVER || \ sessionType == CRYPT_SESSION_TSP_SERVER || \ sessionType == CRYPT_SESSION_CMP_SERVER || \ sessionType == CRYPT_SESSION_SCEP_SERVER ) ? \ TRUE : FALSE; int length, status; /* Create the session */ status = cryptCreateSession( &cryptSession, CRYPT_UNUSED, sessionType ); if( cryptStatusError( status ) ) return( status ); /* Set up the various attributes needed to establish a minimal session */ if( !isServer ) { status = cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_SERVER_NAME, "localhost", 9 ); if( cryptStatusError( status ) ) return( status ); } if( isServer ) { if( !loadRSAContexts( CRYPT_UNUSED, NULL, &cryptPrivKey ) ) return( CRYPT_ERROR_FAILED ); } if( sessionType == CRYPT_SESSION_SSH || \ sessionType == CRYPT_SESSION_CMP ) { status = cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_USERNAME, SSH_USER_NAME, paramStrlen( SSH_USER_NAME ) ); if( cryptStatusOK( status ) ) { status = cryptSetAttributeString( cryptSession, CRYPT_SESSINFO_PASSWORD, SSH_PASSWORD, paramStrlen( SSH_PASSWORD ) ); } if( cryptStatusError( status ) ) return( status ); } if( sessionType == CRYPT_SESSION_CMP ) { status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_CMP_REQUESTTYPE, CRYPT_REQUESTTYPE_INITIALISATION ); if( cryptStatusError( status ) ) return( status ); } /* Perform any final session initialisation */ cryptFuzzInit( cryptSession, cryptPrivKey ); /* We're ready to go, start the forkserver and read the mutable data */ #ifndef __WINDOWS__ __afl_manual_init(); #endif /* !__WINDOWS__ */ length = readFileData( fuzzFileName, fuzzFileName, buffer, 4096, 32, TRUE ); if( length < 32 ) return( CRYPT_ERROR_READ ); /* Perform the fuzzing */ ( void ) cryptSetFuzzData( cryptSession, buffer, length ); cryptDestroySession( cryptSession ); if( cryptPrivKey != CRYPT_UNUSED ) cryptDestroyContext( cryptPrivKey ); return( CRYPT_OK ); }