static int fuzzSpecial( const int fuzzType, const char *fuzzFileName ) { CRYPT_CONTEXT cryptPrivKey; BYTE buffer[ 8192 ]; const int minLength = ( fuzzType == 4000 ) ? 2 : 16; int length, status; /* If we're fuzzing bignum ops, load the private key that we'll need */ if( fuzzType == 4000 ) { if( !loadRSAContexts( CRYPT_UNUSED, NULL, &cryptPrivKey ) ) return( CRYPT_ERROR_FAILED ); } /* 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, 8192, minLength, TRUE ); if( length < minLength ) return( CRYPT_ERROR_READ ); /* Process the input file */ if( fuzzType == 4000 ) { BYTE tmpBuffer[ 8192 ]; #if 0 /* We don't do an early-out in order to check that the bignum code can actually reject all invalid input values */ /* Any value that's larger than the modulus will be trivially rejected so there's no point in trying to process it */ if( buffer[ 0 ] > 0x9C ) { cryptDestroyContext( cryptPrivKey ); return( CRYPT_OK ); } #endif /* 0 */ memcpy( tmpBuffer, buffer, length ); status = cryptDecrypt( cryptPrivKey, buffer, length ); if( cryptStatusOK( status ) ) status = cryptEncrypt( cryptPrivKey, buffer, length ); if( cryptStatusOK( status ) ) { /* Make sure that we got back what we started with */ assert( !memcmp( buffer, tmpBuffer, length ) ); } cryptDestroyContext( cryptPrivKey ); }
static int gen_sha2( uchar * inbufp, int bsize, uchar * outbufp) { CRYPT_CONTEXT hashContext; uchar hash[40]; int ansr; memset(hash, 0, 40); if (cryptInit() != CRYPT_OK) { FATAL(MSG_ERROR, "initializing cryptlib"); } if (cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2) != CRYPT_OK) { FATAL(MSG_ERROR, "creating cryptlib hash context"); } cryptEncrypt(hashContext, inbufp, bsize); cryptEncrypt(hashContext, inbufp, 0); cryptGetAttributeString(hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &ansr); cryptDestroyContext(hashContext); cryptEnd(); memcpy(outbufp, hash, ansr); return ansr; }
int gen_hash( unsigned char *inbufp, int bsize, unsigned char *outbufp, CRYPT_ALGO_TYPE alg) { CRYPT_CONTEXT hashContext; unsigned char hash[40]; int ansr = -1; if (alg != CRYPT_ALGO_SHA1 && alg != CRYPT_ALGO_SHA2) return -1; memset(hash, 0, 40); if (cryptInit_wrapper() != CRYPT_OK) return -1; if (cryptCreateContext(&hashContext, CRYPT_UNUSED, alg) != CRYPT_OK) return -1; cryptEncrypt(hashContext, inbufp, bsize); cryptEncrypt(hashContext, inbufp, 0); if (cryptGetAttributeString( hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &ansr) != CRYPT_OK) { return -1; } cryptDestroyContext(hashContext); if (ansr > 0) memcpy(outbufp, hash, ansr); return ansr; }
static int create_keypair(CRYPT_CONTEXT *pCtx, const char *label) { int status; CRYPT_CONTEXT local_context; /* create the RSA context */ status = cryptCreateContext( &local_context, CRYPT_UNUSED, CRYPT_ALGO_RSA ); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while creating keypair context\n", status); return status; } /* set key label -- TODO make label parameter */ status = cryptSetAttributeString( local_context, CRYPT_CTXINFO_LABEL, label, strlen(label)); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while setting privkey label\n", status); goto err_ctx_exit; } /* generate key */ status = cryptGenerateKey( local_context ); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while generating CA keypair\n", status); goto err_ctx_exit; } /* normal (OK) exit */ *pCtx = local_context; return CRYPT_OK; err_ctx_exit: cryptDestroyContext(local_context); return status; }
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; }
static void testStressObjects( void ) { CRYPT_HANDLE *handleArray = malloc( NO_OBJECTS * sizeof( CRYPT_HANDLE ) ); BYTE hash[ CRYPT_MAX_HASHSIZE ]; int i, length, status; printf( "Running object stress test." ); assert( handleArray != NULL ); for( i = 0; i < NO_OBJECTS; i++ ) { status = cryptCreateContext( &handleArray[ i ], CRYPT_UNUSED, CRYPT_ALGO_SHA ); if( cryptStatusError( status ) ) printf( "cryptEncrypt() failed at %d with status %d.\n", i, status ); } printf( "." ); for( i = 0; i < NO_OBJECTS; i++ ) { status = cryptEncrypt( handleArray[ i ], "12345678", 8 ); if( cryptStatusError( status ) ) printf( "cryptEncrypt() failed at %d with status %d.\n", i, status ); } printf( "." ); for( i = 0; i < NO_OBJECTS; i++ ) { status = cryptEncrypt( handleArray[ i ], "", 0 ); if( cryptStatusError( status ) ) printf( "cryptEncrypt() failed at %d with status %d.\n", i, status ); } printf( "." ); for( i = 0; i < NO_OBJECTS; i++ ) { status = cryptGetAttributeString( handleArray[ i ], CRYPT_CTXINFO_HASHVALUE, hash, &length ); if( cryptStatusError( status ) ) printf( "cryptEncrypt() failed at %d with status %d.\n", i, status ); } printf( "." ); for( i = 0; i < NO_OBJECTS; i++ ) { status = cryptDestroyContext( handleArray[ i ] ); if( cryptStatusError( status ) ) printf( "cryptEncrypt() failed at %d with status %d.\n", i, status ); } free( handleArray ); puts( "." ); }
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; }
unsigned __stdcall processDataThread( void *arg ) { CRYPT_CONTEXT cryptContext; BYTE buffer[ 1024 ]; int threadNo = ( int ) arg; int status; randSleep(); memset( buffer, '*', 1024 ); status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_3DES ); if( cryptStatusOK( status ) ) { randSleep(); status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY, "123456781234567812345678", 24 ); } if( cryptStatusOK( status ) ) { randSleep(); status = cryptEncrypt( cryptContext, buffer, 1024 ); } if( cryptStatusOK( status ) ) { randSleep(); status = cryptEncrypt( cryptContext, buffer, 0 ); } if( cryptStatusOK( status ) ) { randSleep(); status = cryptDestroyContext( cryptContext ); } if( cryptStatusError( status ) ) printf( "\nEncryption failed with status %d.\n", status ); else printf( "%d ", threadNo ); _endthreadex( 0 ); return( 0 ); }
static int exec_gencrl(int argc, char **argv) { CRYPT_KEYSET cakeys, store; CRYPT_CERTIFICATE crl; CRYPT_CONTEXT ca_privkey; const char *dbfilename; char cakeysfilename[4096]; int status; if (argc < 2) { fprintf(stderr, "missing dbfilename/outfilename\n"); return 1; } dbfilename = argv[0]; /* 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 = cryptCACertManagement(&crl, CRYPT_CERTACTION_ISSUE_CRL, store, ca_privkey, CRYPT_UNUSED); WARN_AND_RETURN_IF(status); status = export_cert(crl, argv[1]); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(crl); WARN_AND_RETURN_IF(status); status = cryptKeysetClose(store); WARN_AND_RETURN_IF(status); status = cryptDestroyContext(ca_privkey); WARN_AND_RETURN_IF(status); 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 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; }
void show_export_crl_dialog(FRONTEND * fe) { /* export dialog -> * dialog (OK, cancel), * filename entry & browse, * format choice (DER, text) */ GtkWidget *dlg; GtkEntry *filename_entry; GtkButton *browse_button; GtkRadioButton *rb_text, *rb_der; GtkBox *box; gint result; dlg = gtk_dialog_new_with_buttons("Export CRL", GTK_WINDOW(fe->mainWindow), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); box = GTK_BOX(gtk_hbox_new(0, 5)); gtk_box_pack_start(box, gtk_label_new("Export to"), FALSE, FALSE, 0); filename_entry = GTK_ENTRY(gtk_entry_new()); gtk_box_pack_start(box, GTK_WIDGET(filename_entry), FALSE, FALSE, 0); browse_button = GTK_BUTTON(gtk_button_new_with_mnemonic("_Browse...")); gtk_box_pack_start(box, GTK_WIDGET(browse_button), FALSE, FALSE, 0); g_signal_connect(G_OBJECT(browse_button), "clicked", G_CALLBACK(on_browse_button_clicked), dlg); /* don't ref the entry -- same lifetime */ g_object_set_data_full(G_OBJECT(browse_button), "entry", filename_entry, NULL); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), GTK_WIDGET(box), FALSE, FALSE, 0); rb_der = GTK_RADIO_BUTTON(gtk_radio_button_new_with_mnemonic (NULL, "_DER (Binary)")); rb_text = GTK_RADIO_BUTTON(gtk_radio_button_new_with_mnemonic_from_widget (rb_der, "_PEM (Text)")); box = GTK_BOX(gtk_hbox_new(0, 5)); gtk_box_pack_start(box, gtk_label_new("Format:"), FALSE, FALSE, 0); gtk_box_pack_start(box, GTK_WIDGET(rb_der), FALSE, FALSE, 0); gtk_box_pack_start(box, GTK_WIDGET(rb_text), FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), GTK_WIDGET(box), FALSE, FALSE, 0); gtk_widget_show_all(GTK_WIDGET(GTK_DIALOG(dlg)->vbox)); result = gtk_dialog_run(GTK_DIALOG(dlg)); if (result == GTK_RESPONSE_ACCEPT) { void *buf; int status; int len; gboolean text_format; CRYPT_CERTFORMAT_TYPE fmt; FILE *f; gchar *filename; CRYPT_CERTIFICATE crl; CRYPT_CONTEXT key; gchar *password; /* get password */ password = do_get_password(GTK_WINDOW(dlg)); if (password == NULL) { /* cancelled? */ goto cleanup; } /* sign */ status = lmz_ca_get_signing_key(fe->db, password, &key); g_free(password); /* dynamic */ if (status == CRYPT_ERROR_WRONGKEY) { show_error_dialog(GTK_WINDOW(dlg), "Wrong password"); goto cleanup; } else if (!cryptStatusOK(status)) { show_error_dialog(GTK_WINDOW(dlg), "Error getting signing key (cryptlib error %d)", status); goto cleanup; } status = lmz_ca_gen_crl(fe->db, &crl); if (cryptStatusOK(status)) { /* sign it */ status = cryptSignCert(crl, key); if (cryptStatusOK(status)) { text_format = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rb_text)); fmt = text_format ? CRYPT_CERTFORMAT_TEXT_CERTIFICATE : CRYPT_CERTFORMAT_CERTIFICATE; status = cryptExportCert(NULL, 0, &len, fmt, crl); buf = malloc(len); status = cryptExportCert(buf, len, &len, fmt, crl); if (cryptStatusOK(status)) { filename = g_filename_from_utf8(gtk_entry_get_text(filename_entry), -1, NULL, NULL, NULL); if (filename != NULL) { f = fopen(filename, "w"); if (f != NULL) { if (fwrite(buf, len, 1, f) != 1) { show_error_dialog(NULL, "error fully writing data"); } fclose(f); } else { show_error_dialog(NULL, "error opening file for writing"); } g_free(filename); } else { show_error_dialog(NULL, "filename conversion error"); } free(buf); } } else { show_error_dialog(NULL, "error signing crl (cl error %d)", status); } cryptDestroyCert(crl); } else { show_error_dialog(NULL, "error generating crl (cl error %d)", status); } cryptDestroyContext(key); } cleanup: gtk_widget_destroy(dlg); }
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 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 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 ); }
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 exec_create(int argc, char **argv) { CRYPT_KEYSET keyset; CRYPT_CERTIFICATE cert; CRYPT_CONTEXT context; int status; const char *filename = argv[0]; char keyfilename[4096]; /* PATH_MAX */ char certfilename[4096]; /* PATH_MAX */ /* create the tables using cryptlib */ status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, filename, CRYPT_KEYOPT_CREATE); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while opening keyset\n", status); return 1; } status = cryptKeysetClose(keyset); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while closing keyset\n", status); return 1; } if (opt_verbose) fprintf(stdout, "file %s created OK as cert keyset store\n", filename); /* the database has been created, but there is still no CA key * and CA cert -- now we generate it and put the CA key in a file * and import the public key & cert into the db. */ status = create_keypair(&context, DEFAULT_CA_PRIVKEY_LABEL); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while generating CA keypair\n", status); return 1; } /* generate cert */ status = create_selfsigned_cert(context, DEFAULT_DN, &cert); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while generating CA cert\n", status); goto err_ctx_exit; } snprintf(keyfilename, 4095, "%s.keys", filename); status = save_ca_keypair_and_cert_to_file(context, cert, keyfilename, DEFAULT_PASSWORD); /* TODO password */ if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while saving CA keypair to %s\n", status, keyfilename); goto err_ctx_exit; } if (opt_verbose) fprintf(stdout, "CA keys saved to file keyset %s\n", filename); /* save it */ snprintf(certfilename, 4095, "%s.ca.crt", filename); status = export_cert(cert, certfilename); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while saving CA cert\n", status); goto err_cert_exit; } #if 0 /* add to store */ status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, filename, CRYPT_KEYOPT_NONE); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while opening CA cert store to save CA cert\n", status); goto err_cert_exit; } status = add_ca_cert_to_store(keyset, DEFAULT_DN, cert); /* status = cryptCAAddItem(keyset, cert); */ if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while saving CA cert to CA cert store\n", status); cryptKeysetClose(keyset); goto err_cert_exit; } status = cryptKeysetClose(keyset); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while closing CA cert store\n", status); goto err_cert_exit; } if (opt_verbose) fprintf(stdout, "CA certs for %s saved to %s\n", DEFAULT_DN, filename); #endif /* cleanup */ status = cryptDestroyCert(cert); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while destroying CA cert\n", status); goto err_ctx_exit; } status = cryptDestroyContext(context); if (!cryptStatusOK(status)) { fprintf(stderr, "cryptlib error %d while destroying CA keypair context\n", status); /* NO ERROR CASE */ return 1; } return 0; err_cert_exit: cryptDestroyCert(cert); err_ctx_exit: cryptDestroyContext(context); return 1; }
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 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 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; }
const char *signCMSBlob( struct CMSBlob *cms, const char *keyfilename) { bool sigKeyContext_initialized = false; CRYPT_CONTEXT sigKeyContext; CRYPT_KEYSET cryptKeyset; bool hashContext_initialized = false; CRYPT_CONTEXT hashContext; int tbs_lth; /* to-be-signed length */ unsigned char *tbsp = NULL; /* to-be-signed pointer */ unsigned char *hash[40]; /* stores sha256 message digest */ int signatureLength; /* RSA signature length */ unsigned char *signature = NULL; /* RSA signature bytes */ const char *errmsg = NULL; struct SignerInfo *signerInfop = (struct SignerInfo *)member_casn(&cms->content.signedData.signerInfos. self, 0); struct BlobEncapsulatedContentInfo *encapContentInfop = &cms->content.signedData.encapContentInfo; if (vsize_casn(&signerInfop->signedAttrs.self) == 0) { if ((tbs_lth = vsize_casn(&encapContentInfop->eContent)) < 0) { errmsg = "sizing eContent"; return errmsg; } tbsp = (unsigned char *)calloc(1, tbs_lth); if (!tbsp) { errmsg = "out of memory"; return errmsg; } tbs_lth = read_casn(&encapContentInfop->eContent, tbsp); } else { // get the size of signed attributes and allocate space for them if ((tbs_lth = size_casn(&signerInfop->signedAttrs.self)) < 0) { errmsg = "sizing SignerInfo"; return errmsg; } tbsp = (unsigned char *)calloc(1, tbs_lth); if (!tbsp) { errmsg = "out of memory"; return errmsg; } // DER-encode signedAttrs tbs_lth = encode_casn(&signerInfop->signedAttrs.self, tbsp); *tbsp = ASN_SET; /* replace ASN.1 identifier octet with ASN_SET * (0x31) */ } // compute SHA-256 of signedAttrs if (cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2) < 0 || !(hashContext_initialized = true)) errmsg = "creating hash context"; else if (cryptEncrypt(hashContext, tbsp, tbs_lth) < 0 || cryptEncrypt(hashContext, tbsp, 0) < 0) errmsg = "hashing attrs"; else if (cryptGetAttributeString(hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &signatureLength) < 0) errmsg = "getting attr hash"; // get the key and sign it else if (cryptKeysetOpen(&cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyfilename, CRYPT_KEYOPT_READONLY) < 0) errmsg = "opening key set"; else if (cryptCreateContext(&sigKeyContext, CRYPT_UNUSED, CRYPT_ALGO_RSA) < 0 || !(sigKeyContext_initialized = true)) errmsg = "creating RSA context"; else if (cryptGetPrivateKey(cryptKeyset, &sigKeyContext, CRYPT_KEYID_NAME, "label", "password") < 0) errmsg = "getting key"; else if (cryptCreateSignature(NULL, 0, &signatureLength, sigKeyContext, hashContext) < 0) errmsg = "signing"; // compute signature else if ((signature = (unsigned char *)calloc(1, signatureLength + 20)) == 0) errmsg = "out of memory"; // second parameter is signatureMaxLength, so we allow a little more else if (cryptCreateSignature (signature, signatureLength + 20, &signatureLength, sigKeyContext, hashContext) < 0) errmsg = "signing"; // verify that the signature is right else if (cryptCheckSignature(signature, signatureLength, sigKeyContext, hashContext) < 0) errmsg = "verifying"; if (hashContext_initialized) { cryptDestroyContext(hashContext); hashContext_initialized = false; } if (sigKeyContext_initialized) { cryptDestroyContext(sigKeyContext); sigKeyContext_initialized = false; } if (!errmsg) { struct SignerInfo sigInfo; SignerInfo(&sigInfo, (ushort) 0); decode_casn(&sigInfo.self, signature); // copy the signature into the object copy_casn(&signerInfop->signature, &sigInfo.signature); delete_casn(&sigInfo.self); } if (signature) free(signature); if (tbsp) free(tbsp); return errmsg; }
int main(int argc, char **argv) { int status; CRYPT_CONTEXT cryptContext; CRYPT_KEYSET cryptKeyset; printf("Initializing cryptlib\n"); status = cryptInit(); if (status != CRYPT_OK) { fprintf(stderr, "Error initializing cryptlib\n"); return 1; } /* Create an RSA public/private key context, set a label for it, and generate a key into it */ status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_RSA ); if (status != CRYPT_OK) { fprintf(stderr, "Error creating crypt_context\n"); return 1; } status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_LABEL, "Private key", 11 ); if (status != CRYPT_OK) { fprintf(stderr, "Error setting key label\n"); return 1; } fprintf(stderr, "Generating RSA key\n"); status = cryptGenerateKey( cryptContext ); if (status != CRYPT_OK) { fprintf(stderr, "Error generating key\n"); return 1; } fprintf(stderr, "done!\n"); /* Save the generated public/private key pair to a keyset */ status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, KEY_FILENAME, CRYPT_KEYOPT_CREATE ); if (status != CRYPT_OK) { fprintf(stderr, "Error opening keyset\n"); return 1; } status = cryptAddPrivateKey( cryptKeyset, cryptContext, PASSWORD ); if (status != CRYPT_OK) { fprintf(stderr, "Error adding key to keyset\n"); return 1; } status = cryptKeysetClose( cryptKeyset ); if (status != CRYPT_OK) { fprintf(stderr, "Error closing keyset\n"); return 1; } /* Create CSR */ createCSR(cryptContext); /* Create CA cert */ createCACert(cryptContext); /* Clean up */ status = cryptDestroyContext( cryptContext ); if (status != CRYPT_OK) { fprintf(stderr, "Error destroying context\n"); return 1; } printf("Deinitializing cryptlib\n"); status = cryptEnd(); if (status != CRYPT_OK) { fprintf(stderr, "Error deinitializing cryptlib\n"); return 1; } 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_sign(int argc, char **argv) { const char *id, *dbfilename, *certfilename; char cakeysfilename[4096]; CRYPT_KEYID_TYPE id_type; CRYPT_KEYSET store, cakeys; CRYPT_CERTIFICATE cert, csr; CRYPT_CONTEXT ca_privkey; int status; if (argc != 4) { fprintf(stderr, "usage: sign dbfile (-e email | -n name) certfile\n"); return 1; } dbfilename = argv[0]; certfilename = argv[3]; id = argv[2]; 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: sign dbfile (-e email | -n name) certfile\n"); return 1; } status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE); WARN_AND_RETURN_IF(status); status = cryptCAGetItem(store, &csr, CRYPT_CERTTYPE_CERTREQUEST, id_type, id); WARN_AND_RETURN_IF(status); 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); status = cryptCACertManagement(&cert, CRYPT_CERTACTION_ISSUE_CERT, store, ca_privkey, csr); if (!cryptStatusOK(status)) { int errorLocus; int errorType; cryptGetAttribute(store, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus); cryptGetAttribute(store, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType); fprintf(stderr, "store: locus %d type %d\n", errorLocus, errorType); cryptGetAttribute(csr, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus); cryptGetAttribute(csr, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType); fprintf(stderr, "csr: locus %d type %d\n", errorLocus, errorType); cryptGetAttribute(ca_privkey, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus); cryptGetAttribute(ca_privkey, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType); fprintf(stderr, "ca_privkey: locus %d type %d\n", errorLocus, errorType); } WARN_AND_RETURN_IF(status); status = export_cert(cert, certfilename); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(cert); WARN_AND_RETURN_IF(status); status = cryptDestroyCert(csr); 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 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 ); }
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__); }
const char *signCMS( struct CMS *cms, const char *keyfilename, bool bad) { bool hashContext_initialized = false; CRYPT_CONTEXT hashContext; bool sigKeyContext_initialized = false; CRYPT_CONTEXT sigKeyContext; CRYPT_KEYSET cryptKeyset; int signatureLength; int tbs_lth; char *msg = (char *)0; uchar *tbsp; uchar *signature = NULL; uchar hash[40]; struct casn *sidp; struct Attribute *attrp; struct AttrTableDefined *attrtdp; struct SignerInfo *sigInfop; // signer info // firat clear out any old stuff in signerInfos that may have been put // there by old code while (num_items(&cms->content.signedData.signerInfos.self) > 0) eject_casn(&cms->content.signedData.signerInfos.self, 0); sigInfop = (struct SignerInfo *) inject_casn(&(cms->content.signedData.signerInfos.self), 0); // write the signature version (3) to the signer info write_casn_num(&sigInfop->version.self, 3); // find the SID if ((sidp = findSID(cms)) == NULL) return "finding SID"; // copy the CMS's SID over to the signature's SID copy_casn(&sigInfop->sid.subjectKeyIdentifier, sidp); // use sha256 as the algorithm write_objid(&sigInfop->digestAlgorithm.algorithm, id_sha256); // no parameters to sha256 write_casn(&sigInfop->digestAlgorithm.parameters.sha256, (uchar *) "", 0); // first attribute: content type attrp = (struct Attribute *)inject_casn(&sigInfop->signedAttrs.self, 0); write_objid(&attrp->attrType, id_contentTypeAttr); attrtdp = (struct AttrTableDefined *)inject_casn(&attrp->attrValues.self, 0); copy_casn(&attrtdp->contentType, &cms->content.signedData.encapContentInfo.eContentType); // second attribute: message digest attrp = (struct Attribute *)inject_casn(&sigInfop->signedAttrs.self, 1); write_objid(&attrp->attrType, id_messageDigestAttr); // create the hash for the content // first pull out the content if ((tbs_lth = readvsize_casn(&cms->content.signedData.encapContentInfo.eContent. self, &tbsp)) < 0) return "getting content"; // set up the context, initialize crypt memset(hash, 0, 40); if (cryptInit_wrapper() != CRYPT_OK) return "initializing cryptlib"; // the following calls function f, and if f doesn't return 0 sets // msg to m, then breaks out of the loop. Used immediately below. #define CALL(f,m) if (f != 0) { msg = m; break; } // use a "do { ... } while (0)" loop to bracket this code, so we can // bail out on failure. (Note that this construct isn't really a // loop; it's a way to use break as a more clean version of goto.) do { // first sign the body of the message // create the context CALL(cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2), "creating context"); hashContext_initialized = true; // generate the hash CALL(cryptEncrypt(hashContext, tbsp, tbs_lth), "hashing"); CALL(cryptEncrypt(hashContext, tbsp, 0), "hashing"); // get the hash value. then we're done, so destroy it CALL(cryptGetAttributeString (hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &signatureLength), "getting first hash"); CALL(cryptDestroyContext(hashContext), "destroying intermediate context"); // insert the hash as the first attribute attrtdp = (struct AttrTableDefined *)inject_casn(&attrp->attrValues.self, 0); write_casn(&attrtdp->messageDigest, hash, signatureLength); // create signing time attribute; mark the signing time as now if (getenv("RPKI_NO_SIGNING_TIME") == NULL) { attrp = (struct Attribute *)inject_casn(&sigInfop->signedAttrs.self, 2); write_objid(&attrp->attrType, id_signingTimeAttr); attrtdp = (struct AttrTableDefined *)inject_casn(&attrp->attrValues.self, 0); write_casn_time(&attrtdp->signingTime.utcTime, time((time_t *) 0)); } // we are all done with the content free(tbsp); // now sign the attributes // get the size of signed attributes and allocate space for them if ((tbs_lth = size_casn(&sigInfop->signedAttrs.self)) < 0) { msg = "sizing SignerInfo"; break; } tbsp = (uchar *) calloc(1, tbs_lth); encode_casn(&sigInfop->signedAttrs.self, tbsp); *tbsp = ASN_SET; // create a new, fresh hash context for hashing the attrs, and hash // them CALL(cryptCreateContext(&hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA2), "creating hash context"); CALL(cryptEncrypt(hashContext, tbsp, tbs_lth), "hashing attrs"); CALL(cryptEncrypt(hashContext, tbsp, 0), "hashing attrs"); // get the hash value CALL(cryptGetAttributeString (hashContext, CRYPT_CTXINFO_HASHVALUE, hash, &signatureLength), "getting attr hash"); // get the key and sign it CALL(cryptKeysetOpen (&cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyfilename, CRYPT_KEYOPT_READONLY), "opening key set"); CALL(cryptCreateContext(&sigKeyContext, CRYPT_UNUSED, CRYPT_ALGO_RSA), "creating RSA context"); sigKeyContext_initialized = true; CALL(cryptGetPrivateKey (cryptKeyset, &sigKeyContext, CRYPT_KEYID_NAME, "label", "password"), "getting key"); CALL(cryptCreateSignature (NULL, 0, &signatureLength, sigKeyContext, hashContext), "signing"); // check the signature to make sure it's right signature = (uchar *) calloc(1, signatureLength + 20); // second parameter is signatureMaxLength, so we allow a little more CALL(cryptCreateSignature (signature, signatureLength + 20, &signatureLength, sigKeyContext, hashContext), "signing"); // verify that the signature is right CALL(cryptCheckSignature (signature, signatureLength, sigKeyContext, hashContext), "verifying"); // end of protected block } while (0); // done with cryptlib, shut it down if (hashContext_initialized) { cryptDestroyContext(hashContext); hashContext_initialized = false; } if (sigKeyContext_initialized) { cryptDestroyContext(sigKeyContext); sigKeyContext_initialized = false; } // did we have any trouble above? if so, bail if (msg != 0) { return msg; } // ok, write the signature back to the object struct SignerInfo sigInfo; SignerInfo(&sigInfo, (ushort) 0); decode_casn(&sigInfo.self, signature); // were we supposed to make a bad signature? if so, make it bad if (bad) { uchar *sig; int siz = readvsize_casn(&sigInfo.signature, &sig); sig[0]++; write_casn(&sigInfo.signature, sig, siz); free(sig); } // copy the signature into the object copy_casn(&sigInfop->signature, &sigInfo.signature); delete_casn(&sigInfo.self); // all done with it now free(signature); // Mark it as encrypted with rsa, no params. // See http://www.ietf.org/mail-archive/web/sidr/current/msg04813.html for // why we use id_rsadsi_rsaEncryption instead of id_sha_256WithRSAEncryption // here. write_objid(&sigInfop->signatureAlgorithm.algorithm, id_rsadsi_rsaEncryption); write_casn(&sigInfop->signatureAlgorithm.parameters.self, (uchar *) "", 0); // no errors, we return NULL return NULL; }
int main( int argc, char *argv[] ) { int n; FILE *f; char *buf[8]; char *outFile; char *keyFile; char *certFile; char *certData; char *label; char *secret; struct stat st; int usage; RSA *key; EVP_PKEY *evp; CRYPT_KEYSET keyset; CRYPT_CONTEXT pKey; CRYPT_PKCINFO_RSA rsa; CRYPT_CERTIFICATE cert; CRYPT_KEYOPT_TYPE opt; if ( argc != 6 ) { fprintf( stderr, "Syntax: %s <key> <cert> <out> <label> <secret>\n", argv[0] ); exit( -1 ); } keyFile = argv[1]; certFile = argv[2]; outFile = argv[3]; label = argv[4]; secret = argv[5]; if ( ( f = fopen( keyFile, "r" ) ) == NULL || ( evp = PEM_read_PrivateKey( f, NULL, NULL, NULL ) ) == NULL || ( key = EVP_PKEY_get1_RSA( evp ) ) == NULL ) { fprintf( stderr, "Couldn't load private key from '%s'\n", keyFile ); if ( f ) { ERR_print_errors_fp( stderr ); fclose( f ); } if ( evp ) EVP_PKEY_free( evp ); exit( -1 ); } if ( ( f = fopen( certFile, "r" ) ) == NULL || fstat( fileno( f ), &st ) < 0 || ( certData = malloc( st.st_size ) ) == NULL || fread( certData, 1, st.st_size, f ) < st.st_size ) { fprintf( stderr, "Couldn't load certificate from '%s'\n", certFile ); if ( f ) fclose( f ); free( certData ); exit( -1 ); } /* Should we create a keyset, or append to an existing one? */ opt = CRYPT_KEYOPT_CREATE; f = fopen( outFile, "r" ); if ( f != NULL ) { opt = CRYPT_KEYOPT_NONE; fclose( f ); } cryptInit(); cryptInitComponents( &rsa, CRYPT_KEYTYPE_PRIVATE ); if ( ( buf[0] = malloc( BN_num_bytes( key->n ) ) ) != NULL && ( buf[1] = malloc( BN_num_bytes( key->e ) ) ) != NULL && ( buf[2] = malloc( BN_num_bytes( key->d ) ) ) != NULL && ( buf[3] = malloc( BN_num_bytes( key->p ) ) ) != NULL && ( buf[4] = malloc( BN_num_bytes( key->q ) ) ) != NULL && ( buf[5] = malloc( BN_num_bytes( key->iqmp ) ) ) != NULL && ( buf[6] = malloc( BN_num_bytes( key->dmp1 ) ) ) != NULL && ( buf[7] = malloc( BN_num_bytes( key->dmq1 ) ) ) != NULL ) { int i; BN_bn2bin( key->n, buf[0] ); BN_bn2bin( key->e, buf[1] ); BN_bn2bin( key->d, buf[2] ); BN_bn2bin( key->p, buf[3] ); BN_bn2bin( key->q, buf[4] ); BN_bn2bin( key->iqmp, buf[5] ); BN_bn2bin( key->dmp1, buf[6] ); BN_bn2bin( key->dmq1, buf[7] ); cryptSetComponent( (&rsa)->n, buf[0], BN_num_bits( key->n ) ); cryptSetComponent( (&rsa)->e, buf[1], BN_num_bits( key->e ) ); cryptSetComponent( (&rsa)->d, buf[2], BN_num_bits( key->d ) ); cryptSetComponent( (&rsa)->p, buf[3], BN_num_bits( key->p ) ); cryptSetComponent( (&rsa)->q, buf[4], BN_num_bits( key->q ) ); cryptSetComponent( (&rsa)->u, buf[5], BN_num_bits( key->iqmp ) ); cryptSetComponent( (&rsa)->e1, buf[6], BN_num_bits( key->dmp1 ) ); cryptSetComponent( (&rsa)->e2, buf[7], BN_num_bits( key->dmq1 ) ); i = 0; while ( i < 8 ) free( buf[i++] ); } else { fprintf( stderr, "Couldn't initialise PKCINFO_RSA data.\n" ); exit( -1 ); } n = cryptCreateContext( &pKey, CRYPT_UNUSED, CRYPT_ALGO_RSA ); check( n, pKey, "cryptCreateContext" ); n = cryptSetAttributeString( pKey, CRYPT_CTXINFO_LABEL, label, strlen( label ) ); check( n, pKey, "cryptSetAttributeString(LABEL)" ); n = cryptSetAttributeString( pKey, CRYPT_CTXINFO_KEY_COMPONENTS, &rsa, sizeof( CRYPT_PKCINFO_RSA ) ); check( n, pKey, "cryptSetAttributeString(KEY_COMPONENTS)" ); n = cryptImportCert( certData, st.st_size, CRYPT_UNUSED, &cert ); check( n, cert, "cryptImportCert" ); n = cryptGetAttribute( cert, CRYPT_CERTINFO_KEYUSAGE, &usage ); if ( n != CRYPT_OK ) { fprintf( stderr, "Warning: The certificate specifies no KEYUSAGE.\n" "Cryptlib may not permit its use. See " "<http://toroid.org/ams/pemtrans>.\n" ); } n = cryptKeysetOpen( &keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, outFile, opt ); check( n, keyset, "cryptKeysetOpen" ); n = cryptAddPrivateKey( keyset, pKey, secret ); check( n, keyset, "cryptAddPrivateKey" ); n = cryptAddPublicKey( keyset, cert ); check( n, keyset, "cryptAddPublicKey" ); cryptKeysetClose( keyset ); cryptDestroyComponents( &rsa ); cryptDestroyContext( pKey ); cryptDestroyCert( cert ); exit( 0 ); }