Exemplo n.º 1
0
int testQuery( const CRYPT_KEYSET_TYPE keysetType, const C_STR keysetName )
	{
	CRYPT_KEYSET cryptKeyset;
	int count = 0, status;

	/* Open the database keyset */
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, keysetType,
							  keysetName, CRYPT_KEYOPT_READONLY );
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		if( status == CRYPT_ERROR_OPEN )
			return( CRYPT_ERROR_FAILED );
		return( FALSE );
		}

	/* Send the query to the database and read back the results */
	status = cryptSetAttributeString( cryptKeyset, CRYPT_KEYINFO_QUERY,
									  TEXT( "$C='US'" ),
									  paramStrlen( TEXT( "$C='US'" ) ) );
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptKeyset, "Keyset query", status,
							  __LINE__ ) );
	do
		{
		CRYPT_CERTIFICATE cryptCert;

		status = cryptGetPublicKey( cryptKeyset, &cryptCert,
									CRYPT_KEYID_NONE, NULL );
		if( cryptStatusOK( status ) )
			{
			count++;
			cryptDestroyCert( cryptCert );
			}
		}
	while( cryptStatusOK( status ) );
	if( cryptStatusError( status ) && status != CRYPT_ERROR_COMPLETE )
		return( extErrorExit( cryptKeyset, "cryptGetPublicKey()", status,
							  __LINE__ ) );
	if( count < 2 )
		{
		puts( "Only one certificate was returned, this indicates that the "
			  "database backend\nglue code isn't processing ongoing queries "
			  "correctly." );
		return( FALSE );
		}
	printf( "%d certificate(s) matched the query.\n", count );

	/* Close the keyset */
	status = cryptKeysetClose( cryptKeyset );
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	return( TRUE );
	}
Exemplo n.º 2
0
static int exec_addpubkey(int argc, char **argv) {
  CRYPT_KEYSET keyset;
  CRYPT_CERTIFICATE cert;
  const char *certfilename, *keysetfilename;
  void *data;
  int data_len;
  int status;

  if (argc != 2) {
    fprintf(stderr, "usage: addpubkey keyset cert\n");
    return 1;
  }
  keysetfilename = argv[0]; certfilename = argv[1];
  status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keysetfilename, CRYPT_KEYOPT_NONE);
  WARN_AND_RETURN_IF(status);
  data = read_full_file(certfilename, &data_len);
  status = cryptImportCert(data, data_len, CRYPT_UNUSED, &cert);
  WARN_AND_RETURN_IF(status);
  status = cryptAddPublicKey(keyset, cert);
  WARN_AND_RETURN_IF(status);
  status = cryptKeysetClose(keyset);
  WARN_AND_RETURN_IF(status);
  free(data);
  return 0;

}
Exemplo n.º 3
0
int main(
    int argc,
    char **argv)
{
    CRYPT_CONTEXT privKeyContext;
    CRYPT_KEYSET cryptKeyset;
    int ksize;
    if (argc < 3)
    {
        fprintf(stderr, "Usage: %s filename keysize\n", argv[0]);
        return 1;
    }
    if (sscanf(argv[2], "%d", &ksize) != 1)
    {
        fprintf(stderr, "Invalid key size\n");
        return 1;
    }
    if (ksize != STANDARD_KEY_SIZE)
    {
        fprintf(stderr, "Warning: key size %d is not the standard size (%d)\n",
                ksize, STANDARD_KEY_SIZE);
    }
    printf("Making %s with key size %d bits \n", argv[1], ksize);
    if (cryptInit() != CRYPT_OK)
    {
        fprintf(stderr, "Can't open Cryptlib\n");
        return 1;
    }
    if (cryptCreateContext(&privKeyContext, CRYPT_UNUSED, CRYPT_ALGO_RSA) != CRYPT_OK)
    {
        fprintf(stderr, "Can't create cryptlib private key context\n");
        return 1;
    }
    cryptSetAttributeString(privKeyContext, CRYPT_CTXINFO_LABEL, "label", 5);
    cryptSetAttribute(privKeyContext, CRYPT_CTXINFO_KEYSIZE, ksize / 8);
    if (cryptGenerateKey(privKeyContext) != CRYPT_OK)
    {
        fprintf(stderr, "Can't generate key\n");
        return 1;
    }
    if (cryptKeysetOpen(&cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
                    argv[1], CRYPT_KEYOPT_CREATE) != CRYPT_OK)
    {
        fprintf(stderr, "Can't open keyset\n");
        return 1;
    }
    if (cryptAddPrivateKey(cryptKeyset, privKeyContext, "password") != CRYPT_OK)
    {
        fprintf(stderr, "Can't add key to keyset\n");
        return 1;
    }
    cryptKeysetClose(cryptKeyset);
    cryptDestroyContext(privKeyContext);
    cryptEnd();

    return 0;
}
Exemplo n.º 4
0
static int exec_enroll(int argc, char **argv) {
  const char *dbfilename, *dn;
  CRYPT_KEYSET keyset;
  CRYPT_CERTIFICATE pki_user;
  char userID[CRYPT_MAX_TEXTSIZE + 1], issuePW[CRYPT_MAX_TEXTSIZE + 1], revPW[CRYPT_MAX_TEXTSIZE + 1];
  int userIDlen, issuePWlen, revPWlen;
  int status;

  /* get args */
  if (argc != 2) {
    fprintf(stderr, "usage: enroll dbfilename dn\n");
    return 1;
  }
  dbfilename = argv[0]; dn = argv[1];

  status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "(%s:%d) cryptlib error %d while closing CA privkey keyset\n", __FILE__, __LINE__, status);
    return 1;
  }

  status = cryptCreateCert(&pki_user, CRYPT_UNUSED, CRYPT_CERTTYPE_PKIUSER);
  WARN_IF(status);

  status = cryptSetAttributeString(pki_user, CRYPT_CERTINFO_DN, dn, strlen(dn));
  WARN_IF(status);

  status = cryptCAAddItem(keyset, pki_user);
  WARN_IF(status);

  status = cryptKeysetClose(keyset);
  WARN_IF(status);

  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_ID, userID, &userIDlen);
  WARN_IF(status);
  userID[userIDlen] = '\0';
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD, issuePW, &issuePWlen);
  WARN_IF(status);
  issuePW[issuePWlen] = '\0';
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_REVPASSWORD, revPW, &revPWlen);
  WARN_IF(status);
  revPW[revPWlen] = '\0';

  fprintf(stdout, "%s\n", userID);
  fprintf(stdout, "%s\n", issuePW);
  fprintf(stdout, "%s\n", revPW);

  status = cryptDestroyCert(pki_user);
  WARN_IF(status);

  return 0;
}
Exemplo n.º 5
0
unsigned __stdcall signTest( void *arg ) 
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CONTEXT privateKeyContext;
	CRYPT_ENVELOPE cryptEnvelope;
	BYTE buffer[ 1024 ];
	const int count = *( ( int * ) arg );
	int bytesCopied, i, status;

	printf( "SignTest %d.\n", count );

	for( i = 0; i < count; i++ ) 
		{
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, 
								  CRYPT_KEYSET_FILE, TEST_PRIVKEY_FILE, 
								  CRYPT_KEYOPT_READONLY);
		if( cryptStatusOK( status ) )
			status = cryptGetPrivateKey( cryptKeyset, &privateKeyContext, 
										 CRYPT_KEYID_NAME, RSA_PRIVKEY_LABEL, 
										 TEST_PRIVKEY_PASSWORD );
		if( cryptStatusOK( status ) )
			status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, 
										  CRYPT_FORMAT_CMS );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptEnvelope, 
										CRYPT_ENVINFO_SIGNATURE, 
										privateKeyContext );
		if( cryptStatusOK( status ) )
			status = cryptPushData( cryptEnvelope, "message", 7, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptFlushData( cryptEnvelope );
		if( cryptStatusOK( status ) )
			status = cryptPopData( cryptEnvelope, buffer, 1024, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptDestroyContext( privateKeyContext );
		if( cryptStatusOK( status ) )
			status = cryptKeysetClose( cryptKeyset );
		if( cryptStatusOK( status ) )
			status = cryptDestroyEnvelope( cryptEnvelope );
		if( cryptStatusError( status ) )
			{
			_endthreadex( status );
			return( 0 );
			}
		}

	_endthreadex( 0 );
	return( 0 );
	}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
static int exec_info(int argc, char **argv) {
  const char *dbfilename;
  CRYPT_KEYSET keyset;
  CRYPT_CERTIFICATE pki_user;
  char userID[CRYPT_MAX_TEXTSIZE + 1], issuePW[CRYPT_MAX_TEXTSIZE + 1], revPW[CRYPT_MAX_TEXTSIZE + 1];
  int userIDlen, issuePWlen, revPWlen;
  int status;
  CRYPT_KEYID_TYPE id_type;
  const char *id;
  if (argc < 3) return 1;
  dbfilename = argv[0];
  status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "(%s:%d) cryptlib error %d while closing CA privkey keyset\n", __FILE__, __LINE__, status);
    return 1;
  }
  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;
  }
  status = cryptCAGetItem(keyset, &pki_user, CRYPT_CERTTYPE_PKIUSER, id_type, id);
  WARN_IF(status);
  status = cryptKeysetClose(keyset);
  WARN_IF(status);
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_ID, userID, &userIDlen);
  WARN_IF(status);
  userID[userIDlen] = '\0';
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD, issuePW, &issuePWlen);
  WARN_IF(status);
  issuePW[issuePWlen] = '\0';
  status = cryptGetAttributeString(pki_user, CRYPT_CERTINFO_PKIUSER_REVPASSWORD, revPW, &revPWlen);
  WARN_IF(status);
  revPW[revPWlen] = '\0';

  fprintf(stdout, "%s\n", userID);
  fprintf(stdout, "%s\n", issuePW);
  fprintf(stdout, "%s\n", revPW);

  status = cryptDestroyCert(pki_user);
  WARN_IF(status);
  return 0;

}
Exemplo n.º 8
0
static int fuzzKeyset( const char *fuzzFileName )
	{
	CRYPT_KEYSET cryptKeyset;
	int status;

	/* Start the forkserver */
#ifndef __WINDOWS__
	__afl_manual_init();
#endif /* !__WINDOWS__ */

	/* Process the input file */
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
							  fuzzFileName, CRYPT_KEYOPT_READONLY );
	if( cryptStatusOK( status ) )
		cryptKeysetClose( cryptKeyset );

	return( CRYPT_OK );
	}
Exemplo n.º 9
0
static int exec_request(int argc, char **argv) {
  int status;
  const char *dbfilename, *csrfilename;
  void *csr_data;
  int csr_len;
  CRYPT_KEYSET store;
  CRYPT_CERTIFICATE request;

  if (argc != 2) {
    fprintf(stderr, "usage: request dbfilename csrfilename\n");
    return 1;
  };


  dbfilename = argv[0];
  csrfilename = argv[1];
  if (opt_verbose) fprintf(stderr, "exec request db \"%s\" csr \"%s\"\n", dbfilename, csrfilename);

  status = cryptKeysetOpen(&store, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, dbfilename, CRYPT_KEYOPT_NONE);
  if (opt_verbose) fprintf(stderr, "finished opening ks\n");
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "(%s:%d) -> %d\n", __FILE__, __LINE__, status);
    return status;
  }

  csr_data = read_full_file(csrfilename, &csr_len);
  if (opt_verbose) fprintf(stderr, "finished reading csr\n"); fflush(stderr);
  status = cryptImportCert(csr_data, csr_len, CRYPT_UNUSED, &request);
  free(csr_data);
  if (opt_verbose) fprintf(stderr, "finished importing csr\n");
  WARN_AND_RETURN_IF(status);
  status = cryptCAAddItem(store, request);
  WARN_AND_RETURN_IF(status);
  if (opt_verbose) fprintf(stderr, "finished adding csr to  store\n");
  status = cryptDestroyCert(request);
  WARN_AND_RETURN_IF(status);

  status = cryptKeysetClose(store);
  WARN_AND_RETURN_IF(status);
  if (opt_verbose) fprintf(stderr, "finished closing store\n");

  return 0;
}
Exemplo n.º 10
0
static int save_ca_keypair_and_cert_to_file(CRYPT_CONTEXT ctx, CRYPT_CERTIFICATE cert, const char *filename, const char *password) {
  int status;
  CRYPT_KEYSET keyset;

  status = cryptKeysetOpen( &keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, filename, CRYPT_KEYOPT_CREATE );
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while creating ca privkey keyset file %s\n", status, filename);
    return status;
  }

  status = cryptAddPrivateKey( keyset, ctx, password );
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while adding CA privkey to keyset\n", status);
    goto err_keyset_exit;
  }

  status = cryptAddPublicKey( keyset, cert );
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while adding CA cert to keyset\n", status);
    goto err_keyset_exit;
  }

#if 0
  status = cryptAddPublicKey( keyset, ctx );
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while adding CA pubkey to keyset\n", status);
    goto err_keyset_exit;
  }
#endif

  status = cryptKeysetClose( keyset );
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while closing CA privkey keyset\n", status);
    return status; /* what do we do now, close it again? */
  }

  return CRYPT_OK;

err_keyset_exit:
  cryptKeysetClose( keyset ); return status;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
static int updateKey( const int keyBits, const char *certFileName )
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CERTIFICATE cryptCert;
	char filenameBuffer[ FILENAME_BUFFER_SIZE ];
	void *fileNamePtr = filenameBuffer;
	int status;

	/* Import the certificate from the file */
	status = importCertFile( &cryptCert, certFileName );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't import certificate from file, status %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}

	/* Add the certificate to the file */
	filenameFromTemplate( filenameBuffer, SERVER_ECPRIVKEY_FILE_TEMPLATE, 
						  keyBits );
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
							  fileNamePtr, CRYPT_KEYOPT_NONE );
	if( cryptStatusOK( status ) )
		{
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		cryptKeysetClose( cryptKeyset );
		}
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't update private key with certificate, status %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}

	return( TRUE );
	}
Exemplo n.º 13
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 );
	}
Exemplo n.º 14
0
main(int argc, char **argv){
 
  int  ret;            /* Return code */
  int  i;              /* Loop iterator */
  int  bytesCopied;    /* Bytes output by cryptlib enc/dec ops */
  int  reqAttrib;      /* Crypt required attributed */

  CRYPT_ENVELOPE dataEnv;    /* Envelope for enc/dec */
  CRYPT_KEYSET   keyset;     /* GPG keyset */
  CRYPT_CONTEXT   symContext;        /* Key context */
  char            *keyPtr;           /* Pointer to key */
  
  char label[100];           /* Private key label */
  int  labelLength;          /* Length of label */
  char passbuf[1024];        /* Buffer for GPG key passphrase */
  struct termios ts, ots;    /* Strutures for saving/modifying term attribs */

  char        *clrDataPtr;       /* Pointer to clear text */
  int         clrDataSize;       /* Size of clear text */
  int         clrDataFd;             /* Pointer to clear text file */
  char        *encDataPtr;       /* Pointer to encrypted data */
  int         encDataSize;       /* Size of encrypted data */
  int         encDataFd;             /* Pointer to encrypted text file */
  struct stat encDataFileInfo;       /* fstat return for encrypted data file */
  struct passwd *userInfo;       /* Password info for input user */
  char          *keyFile;        /* GPG key ring file name */
  
  uid_t ownerID = getuid();
  struct passwd *owner_pws = getpwuid(ownerID);
  char* owner_pwname = owner_pws->pw_name;//get the user login name;
  char* owner_pwdir = owner_pws->pw_dir;
  char          *fileKeyName;
  *fileKeyName = malloc(strlen(owner_pwname)+strlen(argv[2]+10));

  strcpy(fileKeyName,argv[2]);
  strcat(fileKeyName,".enc.");
  strcat(fileKeyName,owner_pwname);
  strcat(fileKeyName,".key");
  printf("%s\n",fileKeyName);
  
  
  char          *outputFileKeyName = malloc(strlen(argv[1])+strlen(argv[2])+20);
  
  strcpy(outputFileKeyName,argv[2]);
  strcat(outputFileKeyName,".enc.");
  strcat(outputFileKeyName,argv[1]);
  strcat(outputFileKeyName,".key");
  printf("%s\n",outputFileKeyName);
  
 /*==============================================
     Check Check Check Check Check Check
    ==============================================
   */
  if (argc!=3) {printf("Wrong number of arguments\n");exit(1);}
  char *fileName = malloc(strlen(argv[2])+5);
  strcpy(fileName,argv[2]);
  strcat(fileName,".enc");
  
  fileChecker(fileName);
  
  
  
  
 /*=============================================
    Open DATAFILE and get data
    =============================================
 */
  encDataFd=open(fileKeyName,O_RDONLY);
  if (encDataFd<=0){perror("open encData1");exit(encDataFd);}
  ret=fstat(encDataFd,&encDataFileInfo);
  if (ret!=0){perror("fstat encDataFd");exit(ret);}
  encDataSize=encDataFileInfo.st_size;
  encDataPtr=malloc(encDataFileInfo.st_size);
  if (encDataPtr==NULL){perror("malloc encData");exit(__LINE__);}
  ret=read(encDataFd,encDataPtr,encDataSize);
  if (ret!=encDataSize){perror("read encData");exit(ret);}
  close(encDataFd);
   /*==============================================
     Cryptlib initialization
    ==============================================
   */
  //cryptInit();
  //ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL);
  //checkCryptNormal(ret,"cryptAddRandom",__LINE__);
  
 /*=================================================
    Decrypt the key
    =================================================
  */
   
  keyFile=malloc(  strlen(owner_pwdir )
                 + strlen("/.gnupg/secring.gpg") + 1);
  if (keyFile==NULL){perror("malloc");exit(__LINE__);}
  strcpy(keyFile,owner_pwdir);
  strcat(keyFile,"/.gnupg/secring.gpg");
  printf("Getting secret key from <%s>\n",keyFile);

 //Decrypt key
  cryptInit();
  ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL);
  checkCryptNormal(ret,"cryptAddRandom",__LINE__);
  ret=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyFile, CRYPT_KEYOPT_READONLY);
  free(keyFile);
  checkCryptNormal(ret,"cryptKeysetOpen",__LINE__);
  ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_AUTO);
  checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__);
  ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_KEYSET_DECRYPT, keyset);
  checkCryptNormal(ret,"cryptSetAttribute",__LINE__);
  ret=cryptPushData(dataEnv,encDataPtr,encDataSize,&bytesCopied);
  /*  Expect non-zero return -- indicates need private key */
  ret=cryptGetAttribute(dataEnv, CRYPT_ATTRIBUTE_CURRENT, &reqAttrib); 
  if (reqAttrib != CRYPT_ENVINFO_PRIVATEKEY) 
     {printf("Decrypt error\n");exit(ret);}
  ret=cryptGetAttributeString(dataEnv, CRYPT_ENVINFO_PRIVATEKEY_LABEL, label, &labelLength);
  label[labelLength]='\0';
  checkCryptNormal(ret,"cryptGetAttributeString",__LINE__); 

  
  /*===============================================
    Get the passphrase
    ===============================================
  */

  tcgetattr(STDIN_FILENO, &ts);
  ots = ts;


  ts.c_lflag &= ~ECHO;
  ts.c_lflag |= ECHONL;
  tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts);


  tcgetattr(STDIN_FILENO, &ts);
  if (ts.c_lflag & ECHO) {
    fprintf(stderr, "Failed to turn off echo\n");
    tcsetattr(STDIN_FILENO, TCSANOW, &ots);
    exit(1);
  }

  printf("Enter password for <%s>: ",label);
  fflush(stdout);
  fgets(passbuf, 1024, stdin);

  tcsetattr(STDIN_FILENO, TCSANOW, &ots);   

  ret=cryptSetAttributeString(dataEnv, CRYPT_ENVINFO_PASSWORD,
                             passbuf, strlen(passbuf)-1);
  if (ret != CRYPT_OK) {
    if (ret=CRYPT_ERROR_WRONGKEY) {
      printf("Wrong Key\n");
      exit(ret);
    }else{ 
      printf("cryptSetAttributeString line %d returned <%d>\n",__LINE__,ret);
      exit(ret);
    }
  }



  ret=cryptFlushData(dataEnv);
  checkCryptNormal(ret,"cryptFlushData",__LINE__);

  clrDataSize=KEYSIZE;
  clrDataPtr=malloc(clrDataSize);
  if (clrDataPtr==NULL){perror("malloc");exit(__LINE__);}
  bzero(clrDataPtr,clrDataSize);

  ret=cryptPopData(dataEnv,clrDataPtr,clrDataSize,&bytesCopied);
  checkCryptNormal(ret,"cryptPopData",__LINE__);

  ret=cryptDestroyEnvelope(dataEnv);  
  checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__);
  cryptKeysetClose(keyset);
  checkCryptNormal(ret,"cryptKeysetClose",__LINE__);

  printf("Bytes decrypted <%d>\n",bytesCopied);
   for (i=0;i<bytesCopied;i++){printf("%c",clrDataPtr[i]);}
  ret=cryptEnd();
  checkCryptNormal(ret,"cryptEnd",__LINE__);
  
  /*====================================================
    Part2 Encrypt the key with user's private key 
    ====================================================
  */
  
    /*==============================================
     Cryptlib initialization
    ==============================================
   */
  cryptInit();
  ret=cryptAddRandom( NULL , CRYPT_RANDOM_SLOWPOLL);
  checkCryptNormal(ret,"cryptAddRandom",__LINE__);
  /*====================================================
    Get key file name 
    ====================================================
  */
  keyFile=malloc(  strlen(owner_pwdir )
                 + strlen("/.gnupg/pubring.gpg") + 1);
  if (keyFile==NULL){perror("malloc");exit(__LINE__);}
  strcpy(keyFile,owner_pwdir);
  strcat(keyFile,"/.gnupg/pubring.gpg");
  printf("Getting secret key from <%s>\n",keyFile);

  /*====================================================
    Encrypt key with GPG public key
    Email address is for recipient
    ===================================================
  */

  
  ret=cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, keyFile, CRYPT_KEYOPT_READONLY);
  free(keyFile);
  checkCryptNormal(ret,"cryptKeysetOpen",__LINE__);
  ret=cryptCreateEnvelope(&dataEnv, CRYPT_UNUSED, CRYPT_FORMAT_PGP);
  checkCryptNormal(ret,"cryptCreateEnvelope",__LINE__);
  ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_KEYSET_ENCRYPT, keyset);
  checkCryptNormal(ret,"cryptSetAttribute",__LINE__);
  ret=cryptSetAttributeString(dataEnv, CRYPT_ENVINFO_RECIPIENT, 
                              argv[1],strlen(argv[1]));
  checkCryptNormal(ret,"cryptSetAttributeString",__LINE__);
  ret=cryptSetAttribute(dataEnv, CRYPT_ENVINFO_DATASIZE, KEYSIZE);

  ret=cryptPushData(dataEnv,clrDataPtr,KEYSIZE,&bytesCopied);
  checkCryptNormal(ret,"cryptPushData",__LINE__);
  ret=cryptFlushData(dataEnv);
  checkCryptNormal(ret,"cryptFlushData",__LINE__);

  encDataSize=strlen(clrDataPtr)+1+1028;
  encDataPtr=malloc(encDataSize);
  if (encDataPtr==NULL){perror("malloc");exit(__LINE__);}
  ret=cryptPopData(dataEnv,encDataPtr,encDataSize,&bytesCopied);
  printf("cryptPopData returned <%d> bytes of encrypted data\n",bytesCopied);
  encDataSize=bytesCopied;

  ret=cryptDestroyEnvelope(dataEnv);  
  checkCryptNormal(ret,"cryptDestroyEnvelope",__LINE__);
  cryptKeysetClose(keyset);
  checkCryptNormal(ret,"cryptKeysetClose",__LINE__);
  
  /*==============================================
     
        write it to output file.
    ==============================================
  */

  
  printf("%s\n",outputFileKeyName);
  encDataFd=open(outputFileKeyName,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
  if (encDataFd<=0){perror("open encDataFd");exit(encDataFd);}
  ret=write(encDataFd,encDataPtr,bytesCopied);
  if (ret!=bytesCopied){perror("write encData");exit(ret);}
  close(encDataFd);
  int chmodStat = chmod (outputFileKeyName, S_IWRITE| S_IREAD| S_IRGRP | S_IWGRP);
  if(chmodStat<0){
	  perror("failed to chmod");
	  exit(-1);
  }
  free(encDataPtr);

  }
Exemplo n.º 15
0
static int connectCertstoreClient( void )
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CERTIFICATE cryptCert;
	const C_STR cert1ID = TEXT( "*****@*****.**" );
	const C_STR cert2ID = TEXT( "*****@*****.**" );
	int status;

	/* Open the keyset with a check to make sure this access method exists
	   so we can return an appropriate error message */
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_HTTP,
							  TEXT( "localhost" ), CRYPT_KEYOPT_READONLY );
	if( status == CRYPT_ERROR_PARAM3 )
		{
		/* This type of keyset access not available */
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( CRYPT_ERROR_FAILED );
		}


	/* Read a present certificate from the keyset using the ASCII email
	   address */
	status = cryptGetPublicKey( cryptKeyset, &cryptCert, CRYPT_KEYID_EMAIL,
								cert1ID );
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptKeyset, "cryptGetPublicKey()", status,
							  __LINE__ ) );
	printf( "Successfully read certificate for '%s'.\n", cert1ID );
	cryptDestroyCert( cryptCert );

	/* Read a non-present certificate from the keyset */
	status = cryptGetPublicKey( cryptKeyset, &cryptCert, CRYPT_KEYID_EMAIL,
								cert2ID );
	if( status == CRYPT_ERROR_NOTFOUND )
		printf( "Successfully processed not-present code for '%s'.\n",
				cert2ID );
	else
		return( extErrorExit( cryptKeyset, "cryptGetPublicKey()", status,
							  __LINE__ ) );

	/* Read the certificate from the keyset using the base64-encoded certID.
	   Since this uses an internal identifier, we can't actually do it from
	   here, this requires modifying the internal keyset read code to
	   substitute the different identifier type.
	   
	   A second purpose for this call is to test the ability of the client
	   to recover from the CRYPT_ERROR_NOTFOUND in the previous call, i.e.
	   the error should be nonfatal with further requests possible */
	status = cryptGetPublicKey( cryptKeyset, &cryptCert, CRYPT_KEYID_EMAIL,
								cert1ID );
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptKeyset, "cryptGetPublicKey()", status,
							  __LINE__ ) );
	printf( "Successfully read certificate for '%s'.\n", cert1ID );
	cryptDestroyCert( cryptCert );

	/* Clean up */
	cryptKeysetClose( cryptKeyset );
	return( TRUE );
	}
Exemplo n.º 16
0
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;
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
int testReadCertLDAP( void )
	{
	CRYPT_KEYSET cryptKeyset;
	static const char FAR_BSS *ldapErrorString = \
		"LDAP directory read failed, probably because the standard being "
		"used by the\ndirectory server differs from the one used by the "
		"LDAP client software (pick\na standard, any standard).  If you "
		"know how the directory being used is\nconfigured, you can try "
		"changing the CRYPT_OPTION_KEYS_LDAP_xxx settings to\nmatch those "
		"used by the server.  Processing will continue without treating\n"
		"this as a fatal error.\n";
	const C_STR ldapKeysetName = ldapUrlInfo[ LDAP_SERVER_NO ].url;
	char ldapAttribute1[ CRYPT_MAX_TEXTSIZE + 1 ];
	char ldapAttribute2[ CRYPT_MAX_TEXTSIZE + 1 ];
	char certName[ CRYPT_MAX_TEXTSIZE ], caCertName[ CRYPT_MAX_TEXTSIZE ];
	char crlName[ CRYPT_MAX_TEXTSIZE ];
	int length, status;

	/* LDAP directories come and go, check to see which one is currently
	   around */
	puts( "Testing LDAP directory availability..." );
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_LDAP,
							  ldapKeysetName, CRYPT_KEYOPT_READONLY );
	if( status == CRYPT_ERROR_PARAM3 )
		{
		/* LDAP keyset access not available */
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( status == CRYPT_ERROR_OPEN )
		{
		printf( "%s not available for some odd reason,\n  trying "
				"alternative directory instead...\n", 
				ldapUrlInfo[ LDAP_SERVER_NO ].asciiURL );
		ldapKeysetName = ldapUrlInfo[ LDAP_ALT_SERVER_NO ].url;
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
								  CRYPT_KEYSET_LDAP, ldapKeysetName,
								  CRYPT_KEYOPT_READONLY );
		}
	if( status == CRYPT_ERROR_OPEN )
		{
		printf( "%s not available either.\n",
				ldapUrlInfo[ LDAP_ALT_SERVER_NO ].asciiURL );
		puts( "None of the test LDAP directories are available.  If you need "
			  "to test the\nLDAP capabilities, you need to set up an LDAP "
			  "directory that can be used\nfor the certificate store.  You "
			  "can configure the LDAP directory using the\nLDAP_KEYSET_xxx "
			  "settings in test/test.h.  Alternatively, if this message\n"
			  "took a long time to appear you may be behind a firewall that "
			  "blocks LDAP\ntraffic.\n" );
		return( FALSE );
		}
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptGetAttributeString( CRYPT_UNUSED,
									  CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS,
									  ldapAttribute1, &length );
	if( cryptStatusOK( status ) )
		{
#ifdef UNICODE_STRINGS
		length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
		ldapAttribute1[ length ] = TEXT( '\0' );
		status = cryptGetAttributeString( cryptKeyset,
										  CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS,
										  ldapAttribute2, &length );
		}
	if( cryptStatusOK( status ) )
		{
#ifdef UNICODE_STRINGS
		length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
		ldapAttribute2[ length ] = TEXT( '\0' );
		}
	if( cryptStatusError( status ) || \
		strcmp( ldapAttribute1, ldapAttribute2 ) )
		{
		printf( "Failed to get/set keyset attribute via equivalent global "
				"attribute, error\ncode %d, value '%s', should be\n'%s', "
				"line %d.\n", status, ldapAttribute2, ldapAttribute1,
				__LINE__ );
		return( FALSE );
		}
	cryptKeysetClose( cryptKeyset );
	printf( "  LDAP directory %s seems to be up, using that for read test.\n",
			ldapKeysetName );

	/* Now it gets tricky, we have to jump through all sorts of hoops to
	   run the tests in an automated manner since the innate incompatibility
	   of LDAP directory setups means that even though cryptlib's LDAP access
	   code retries failed queries with various options, we still need to
	   manually override some settings here.  The simplest option is a direct
	   read with no special-case handling */
	if( !paramStrcmp( ldapKeysetName, ldapUrlInfo[ LDAP_SERVER_NO ].url ) )
		{
		puts( "Testing LDAP certificate read..." );
		status = testKeysetRead( CRYPT_KEYSET_LDAP, ldapKeysetName,
								 CRYPT_KEYID_NAME,
								 ldapUrlInfo[ LDAP_SERVER_NO ].certName,
								 CRYPT_CERTTYPE_CERTIFICATE,
								 READ_OPTION_NORMAL );
		if( !status )
			{
			/* Since we can never be sure about the LDAP schema du jour, we
			   don't treat a failure as a fatal error */
			puts( ldapErrorString );
			return( FALSE );
			}

		/* This directory doesn't contain CRLs (or at least not at any known
		   location) so we skip the CRL read test */
		puts( "LDAP certificate read succeeded (CRL read skipped).\n" );
		return( TRUE );
		}

	/* The secondary LDAP directory that we're using for these tests doesn't
	   recognise the ';binary' modifier which is required by LDAP servers in
	   order to get them to work properly, we have to change the attribute
	   name around the read calls to the format expected by the server.

	   In addition because the magic formula for fetching a CRL doesn't seem
	   to work for certificates, the CRL read is done first */
	puts( "Testing LDAP CRL read..." );
	status = cryptGetAttributeString( CRYPT_UNUSED, 
									  CRYPT_OPTION_KEYS_LDAP_CRLNAME,
									  crlName, &length );
	if( cryptStatusError( status ) )
		return( FALSE );
#ifdef UNICODE_STRINGS
	length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
	certName[ length ] = TEXT( '\0' );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CRLNAME,
							 "certificateRevocationList", 25 );
	status = testKeysetRead( CRYPT_KEYSET_LDAP, ldapKeysetName,
							 CRYPT_KEYID_NAME,
							 ldapUrlInfo[ LDAP_ALT_SERVER_NO ].crlName,
							 CRYPT_CERTTYPE_CRL, READ_OPTION_NORMAL );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CRLNAME,
							 crlName, strlen( crlName ) );
	if( !status )
		{
		/* Since we can never be sure about the LDAP schema du jour, we
		   don't treat a failure as a fatal error */
		puts( ldapErrorString );
		return( FALSE );
		}

	puts( "Testing LDAP certificate read..." );
	status = cryptGetAttributeString( CRYPT_UNUSED, 
									  CRYPT_OPTION_KEYS_LDAP_CERTNAME,
									  certName, &length );
	if( cryptStatusError( status ) )
		return( FALSE );
#ifdef UNICODE_STRINGS
	length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
	certName[ length ] = TEXT( '\0' );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CERTNAME,
							 "userCertificate", 15 );
	status = cryptGetAttributeString( CRYPT_UNUSED, 
									  CRYPT_OPTION_KEYS_LDAP_CACERTNAME,
									  caCertName, &length );
	if( cryptStatusError( status ) )
		return( FALSE );
#ifdef UNICODE_STRINGS
	length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
	certName[ length ] = TEXT( '\0' );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CACERTNAME,
							 "cACertificate", 13 );
	status = testKeysetRead( CRYPT_KEYSET_LDAP, ldapKeysetName,
							 CRYPT_KEYID_NAME,
							 ldapUrlInfo[ LDAP_ALT_SERVER_NO ].certName,
							 CRYPT_CERTTYPE_CERTIFICATE, READ_OPTION_NORMAL );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CERTNAME,
							 certName, strlen( certName ) );
	cryptSetAttributeString( CRYPT_UNUSED, CRYPT_OPTION_KEYS_LDAP_CACERTNAME,
							 caCertName, strlen( caCertName ) );
	if( !status )
		{
		/* Since we can never be sure about the LDAP schema du jour, we
		   don't treat a failure as a fatal error */
		puts( "LDAP directory read failed, probably due to the magic "
			  "incantatation to fetch\na certificate from this server not "
			  "matching the one used to fetch a CRL.\nProcessing will "
			  "continue without treating this as a fatal error.\n" );
		return( FALSE );
		}
	puts( "LDAP certificate/CRL read succeeded.\n" );

	return( TRUE );
	}
Exemplo n.º 19
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;
}
Exemplo n.º 20
0
static int testKeysetWrite( const CRYPT_KEYSET_TYPE keysetType,
							const C_STR keysetName )
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CERTIFICATE cryptCert;
	CRYPT_CONTEXT pubKeyContext, privKeyContext;
	C_CHR filenameBuffer[ FILENAME_BUFFER_SIZE ];
	C_CHR name[ CRYPT_MAX_TEXTSIZE + 1 ];
	int length, status;

	/* Import the certificate from a file - this is easier than creating one
	   from scratch.  We use one of the later certs in the test set, since
	   this contains an email address, which the earlier ones don't */
	status = importCertFromTemplate( &cryptCert, CERT_FILE_TEMPLATE, 
									 EMAILADDR_CERT_NO );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read certificate from file, status %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Make sure that the certificate does actually contain an email 
	   address */
	status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_EMAIL,
									  name, &length );
	if( cryptStatusError( status ) )
		{
		printf( "Certificate doesn't contain an email address and can't be "
				"used for testing,\n  line %d.\n", __LINE__ );
		return( FALSE );
		}

	/* Create the database keyset with a check to make sure this access
	   method exists so we can return an appropriate error message.  If the
	   database table already exists, this will return a duplicate data
	   error so we retry the open with no flags to open the existing database
	   keyset for write access */
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, keysetType,
							  keysetName, CRYPT_KEYOPT_CREATE );
	if( cryptStatusOK( status ) )
		printf( "Created new certificate database '%s'.\n", keysetName );
	if( status == CRYPT_ERROR_PARAM3 )
		{
		/* This type of keyset access isn't available, return a special error
		   code to indicate that the test wasn't performed, but that this
		   isn't a reason to abort processing */
		cryptDestroyCert( cryptCert );
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( status == CRYPT_ERROR_DUPLICATE )
		status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, keysetType,
								  keysetName, 0 );
	if( cryptStatusError( status ) )
		{
		cryptDestroyCert( cryptCert );
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		if( status == CRYPT_ERROR_OPEN )
			return( CRYPT_ERROR_FAILED );
		return( FALSE );
		}

	/* Write the key to the database */
	puts( "Adding certificate." );
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( status == CRYPT_ERROR_DUPLICATE )
		{
		/* The key is already present, delete it and retry the write */
		status = cryptGetAttributeString( cryptCert,
								CRYPT_CERTINFO_COMMONNAME, name, &length );
		if( cryptStatusOK( status ) )
			{
#ifdef UNICODE_STRINGS
			length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
			name[ length ] = TEXT( '\0' );
			status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name );
			}
		if( cryptStatusError( status ) )
			return( extErrorExit( cryptKeyset, "cryptDeleteKey()", status,
								  __LINE__ ) );
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		}
	if( cryptStatusError( status ) )
		{
		printExtError( cryptKeyset, "cryptAddPublicKey()", status, __LINE__ );

		/* LDAP writes can fail due to the chosen directory not supporting the
		   schema du jour, so we're a bit more careful about cleaning up since
		   we'll skip the error and continue processing */
		cryptDestroyCert( cryptCert );
		cryptKeysetClose( cryptKeyset );
		return( FALSE );
		}
	cryptDestroyCert( cryptCert );

	/* Add a second certificate with C=US so that we've got enough certs to 
	   properly exercise the query code.  This certificate is highly unusual 
	   in that it doesn't have a DN, so we have to move up the DN looking 
	   for higher-up values, in this case the OU */
	if( keysetType != CRYPT_KEYSET_LDAP )
		{
		status = importCertFromTemplate( &cryptCert, CERT_FILE_TEMPLATE, 2 );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't read certificate from file, status %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		if( status == CRYPT_ERROR_DUPLICATE )
			{
			status = cryptGetAttributeString( cryptCert,
							CRYPT_CERTINFO_COMMONNAME, name, &length );
			if( cryptStatusError( status ) )
				status = cryptGetAttributeString( cryptCert,
							CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, name, &length );
			if( cryptStatusOK( status ) )
				{
#ifdef UNICODE_STRINGS
				length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
				name[ length ] = TEXT( '\0' );
				status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name );
				}
			if( cryptStatusOK( status ) )
				status = cryptAddPublicKey( cryptKeyset, cryptCert );
			}
		if( cryptStatusError( status ) )
			return( extErrorExit( cryptKeyset, "cryptAddPublicKey()",
								  status, __LINE__ ) );
		cryptDestroyCert( cryptCert );
		}

	/* Add a third certificate with a DN that'll cause problems for some 
	   storage technologies */
	if( !loadRSAContexts( CRYPT_UNUSED, &pubKeyContext, &privKeyContext ) )
		return( FALSE );
	status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
							  CRYPT_CERTTYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		{
		printf( "cryptCreateCert() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptSetAttribute( cryptCert,
					CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, pubKeyContext );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptCert, "cryptSetAttribute()", status,
							   __LINE__ ) );
	if( !addCertFields( cryptCert, sqlCertData, __LINE__ ) )
		return( FALSE );
	status = cryptSignCert( cryptCert, privKeyContext );
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptCert, "cryptSignCert()", status,
							   __LINE__ ) );
	destroyContexts( CRYPT_UNUSED, pubKeyContext, privKeyContext );
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( cryptStatusError( status ) )
		{
		/* The key is already present, delete it and retry the write */
		status = cryptGetAttributeString( cryptCert,
								CRYPT_CERTINFO_COMMONNAME, name, &length );
		if( cryptStatusOK( status ) )
			{
#ifdef UNICODE_STRINGS
			length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
			name[ length ] = TEXT( '\0' );
			status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name );
			}
		if( cryptStatusError( status ) )
			return( extErrorExit( cryptKeyset, "cryptDeleteKey()", status,
								  __LINE__ ) );
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		}
	if( cryptStatusError( status ) )
		{
		return( extErrorExit( cryptKeyset, "cryptAddPublicKey()",
							  status, __LINE__ ) );
		}
	cryptDestroyCert( cryptCert );

	/* Now try the same thing with a CRL.  This code also tests the
	   duplicate-detection mechanism, if we don't get a duplicate error
	   there's a problem */
	puts( "Adding CRL." );
	status = importCertFromTemplate( &cryptCert, CRL_FILE_TEMPLATE, 1 );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read CRL from file, status %d, line %d.\n", 
				status, __LINE__ );
		return( TRUE );
		}
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE )
		return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
							  __LINE__ ) );
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( status != CRYPT_ERROR_DUPLICATE )
		{
		printf( "Addition of duplicate item to keyset failed to produce "
			    "CRYPT_ERROR_DUPLICATE, status %d, line %d.\n", status,
				__LINE__ );
		return( FALSE );
		}
	cryptDestroyCert( cryptCert );

	/* Finally, try it with a certificate chain */
	puts( "Adding certificate chain." );
	filenameParamFromTemplate( filenameBuffer, CERTCHAIN_FILE_TEMPLATE, 
							   CERT_CHAIN_NO );
	status = importCertFile( &cryptCert, filenameBuffer );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read certificate chain from file, status %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE )
		return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
							  __LINE__ ) );
	cryptDestroyCert( cryptCert );

	/* In addition to the other certs we also add the generic user 
	   certificate, which is used later in other tests.  Since it may have 
	   been added earlier we try and delete it first (we can't use the 
	   existing version since the issuerAndSerialNumber won't match the one 
	   in the private-key keyset) */
	status = getPublicKey( &cryptCert, USER_PRIVKEY_FILE,
						   USER_PRIVKEY_LABEL );
	if( cryptStatusError( status ) )
		{
		printf( "Couldn't read user certificate from file, status %d, line "
				"%d.\n", status, __LINE__ );
		return( FALSE );
		}
	status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_COMMONNAME,
									  name, &length );
	if( cryptStatusError( status ) )
		return( FALSE );
#ifdef UNICODE_STRINGS
	length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
	name[ length ] = TEXT( '\0' );
	do
		status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME, name );
	while( cryptStatusOK( status ) );
	status = cryptAddPublicKey( cryptKeyset, cryptCert );
	if( status == CRYPT_ERROR_NOTFOUND )
		{
		/* This can occur if a database keyset is defined but hasn't been
		   initialised yet so the necessary tables don't exist, it can be
		   opened but an attempt to add a key will return a not found error
		   since it's the table itself rather than any item within it that
		   isn't being found */
		status = CRYPT_OK;
		}
	if( cryptStatusError( status ) )
		return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
							  __LINE__ ) );
	cryptDestroyCert( cryptCert );

	/* Finally, if ECC is enabled we also add ECC certificates that are used
	   later in other tests */
	if( cryptStatusOK( cryptQueryCapability( CRYPT_ALGO_ECDSA, NULL ) ) )
		{
#ifdef UNICODE_STRINGS
		wchar_t wcBuffer[ FILENAME_BUFFER_SIZE ];
#endif /* UNICODE_STRINGS */
		void *fileNamePtr = filenameBuffer;

		/* Add the P256 certificate */
		filenameFromTemplate( filenameBuffer, 
							  SERVER_ECPRIVKEY_FILE_TEMPLATE, 256 );
#ifdef UNICODE_STRINGS
		mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 );
		fileNamePtr = wcBuffer;
#endif /* UNICODE_STRINGS */
		status = getPublicKey( &cryptCert, fileNamePtr,
							   USER_PRIVKEY_LABEL );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't read user certificate from file, status %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE )
			return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
								  __LINE__ ) );
		cryptDestroyCert( cryptCert );

		/* Add the P384 certificate */
		filenameFromTemplate( filenameBuffer, 
							  SERVER_ECPRIVKEY_FILE_TEMPLATE, 384 );
#ifdef UNICODE_STRINGS
		mbstowcs( wcBuffer, filenameBuffer, strlen( filenameBuffer ) + 1 );
		fileNamePtr = wcBuffer;
#endif /* UNICODE_STRINGS */
		status = getPublicKey( &cryptCert, fileNamePtr,
							   USER_PRIVKEY_LABEL );
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't read user certificate from file, status %d, "
					"line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		status = cryptAddPublicKey( cryptKeyset, cryptCert );
		if( cryptStatusError( status ) && status != CRYPT_ERROR_DUPLICATE )
			return( extErrorExit( cryptKeyset, "cryptAddPublicKey()", status,
								  __LINE__ ) );
		cryptDestroyCert( cryptCert );
		}

	/* Make sure the deletion code works properly.  This is an artifact of
	   the way RDBMS' work, the delete query can execute successfully but
	   not delete anything so we make sure the glue code correctly
	   translates this into a CRYPT_DATA_NOTFOUND */
	status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME,
							 TEXT( "Mr.Not Appearing in this Keyset" ) );
	if( status != CRYPT_ERROR_NOTFOUND )
		{
		puts( "Attempt to delete a nonexistant key reports success, the "
			  "database backend glue\ncode needs to be fixed to handle this "
			  "correctly." );
		return( FALSE );
		}

	/* Close the keyset */
	status = cryptKeysetClose( cryptKeyset );
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
				status, __LINE__ );
		}

	return( TRUE );
	}
Exemplo n.º 21
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;
}
Exemplo n.º 22
0
static int testKeysetRead( const CRYPT_KEYSET_TYPE keysetType,
						   const C_STR keysetName,
						   const CRYPT_KEYID_TYPE keyType,
						   const C_STR keyName,
						   const CRYPT_CERTTYPE_TYPE type,
						   const int option )
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CERTIFICATE cryptCert;
	BOOLEAN isCertChain = FALSE;
	int value, status;

	/* Open the keyset with a check to make sure this access method exists
	   so we can return an appropriate error message */
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, keysetType,
							  keysetName, CRYPT_KEYOPT_READONLY );
	if( status == CRYPT_ERROR_PARAM3 )
		{
		/* This type of keyset access not available */
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( CRYPT_ERROR_FAILED );
		}

	/* Read the certificate from the keyset */
	status = cryptGetPublicKey( cryptKeyset, &cryptCert, keyType, keyName );
	if( cryptStatusError( status ) )
		{
		/* The access to network-accessible keysets can be rather
		   temperamental and can fail at this point even though it's not a
		   fatal error.  The calling code knows this and will continue the
		   self-test with an appropriate warning, so we explicitly clean up
		   after ourselves to make sure we don't get a CRYPT_ORPHAN on
		   shutdown */
		if( keysetType == CRYPT_KEYSET_HTTP && \
			status == CRYPT_ERROR_NOTFOUND )
			{
			/* 404's are relatively common, and non-fatal */
			extErrorExit( cryptKeyset, "cryptGetPublicKey()", status, __LINE__ );
			puts( "  (404 is a common HTTP error, and non-fatal)." );
			return( TRUE );
			}

		return( extErrorExit( cryptKeyset, "cryptGetPublicKey()", status,
							  __LINE__ ) );
		}

	/* Make sure that we got what we were expecting */
	status = cryptGetAttribute( cryptCert, CRYPT_CERTINFO_CERTTYPE, 
								&value );
	if( cryptStatusError( status ) || ( value != type ) )
		{
		printf( "Expecting certificate object type %d, got %d, line %d.", 
				type, value, __LINE__ );
		return( FALSE );
		}
	if( value == CRYPT_CERTTYPE_CERTCHAIN )
		isCertChain = TRUE;
	if( value == CRYPT_CERTTYPE_CERTCHAIN || value == CRYPT_CERTTYPE_CRL )
		{
		value = 0;
		cryptSetAttribute( cryptCert, CRYPT_CERTINFO_CURRENT_CERTIFICATE,
						   CRYPT_CURSOR_FIRST );
		do
			value++;
		while( cryptSetAttribute( cryptCert,
								  CRYPT_CERTINFO_CURRENT_CERTIFICATE,
								  CRYPT_CURSOR_NEXT ) == CRYPT_OK );
		printf( isCertChain ? "Certificate chain length = %d.\n" : \
							  "CRL has %d entries.\n", value );
		}

	/* Check the certificate against the CRL.  Any kind of error is a 
	   failure since the certificate isn't in the CRL */
	if( keysetType != CRYPT_KEYSET_LDAP && \
		keysetType != CRYPT_KEYSET_HTTP )
		{
		if( !checkKeysetCRL( cryptKeyset, cryptCert, isCertChain ) )
			return( FALSE );
		}
	cryptDestroyCert( cryptCert );

	/* If we're reading multiple certs using the same (cached) query type,
	   try re-reading the certificate.  This can't be easily tested from the
	   outside because it's database back-end specific, so it'll require
	   attaching a debugger to the read code to make sure that the cacheing
	   is working as required */
	if( option == READ_OPTION_MULTIPLE )
		{
		int i;

		for( i = 0; i < 3; i++ )
			{
			status = cryptGetPublicKey( cryptKeyset, &cryptCert, keyType,
										keyName );
			if( cryptStatusError( status ) )
				{
				printf( "cryptGetPublicKey() with cached query failed with "
						"error code %d, line %d.\n", status, __LINE__ );
				return( FALSE );
				}
			cryptDestroyCert( cryptCert );
			}
		}

	/* Close the keyset */
	status = cryptKeysetClose( cryptKeyset );
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	return( TRUE );
	}
Exemplo n.º 23
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;
}
Exemplo n.º 24
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;
}
Exemplo n.º 25
0
static int connectCertstoreServer( void )
	{
	CRYPT_SESSION cryptSession;
	CRYPT_KEYSET cryptCertStore;
	int connectionActive, status;

	puts( "Testing HTTP certstore server session..." );

	/* Create the HTTP certstore session */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
								 CRYPT_SESSION_CERTSTORE_SERVER );
	if( status == CRYPT_ERROR_PARAM3 )	/* Certstore session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
	if( cryptStatusError( status ) )
		{
		printf( "cryptCreateSession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	if( !setLocalConnect( cryptSession, 80 ) )
		return( FALSE );

	/* Add the certificate store that we'll be using to provide certs (it's
	   actually just the generic database keyset and not the full 
	   certificate store, because this contains more test certs) */
	status = cryptKeysetOpen( &cryptCertStore, CRYPT_UNUSED,
							  DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME,
							  CRYPT_KEYOPT_READONLY );
	if( status == CRYPT_ERROR_PARAM3 )
		{
		/* This type of keyset access isn't available, return a special
		   error code to indicate that the test wasn't performed, but
		   that this isn't a reason to abort processing */
		puts( "SVR: No certificate store available, aborting HTTP certstore "
				  "responder test.\n" );
		cryptDestroySession( cryptSession );
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( cryptStatusOK( status ) )
		{
		status = cryptSetAttribute( cryptSession,
						CRYPT_SESSINFO_KEYSET, cryptCertStore );
		cryptKeysetClose( cryptCertStore );
		}
	if( cryptStatusError( status ) )
		return( attrErrorExit( cryptSession, "SVR: cryptSetAttribute()",
							   status, __LINE__ ) );

	/* Activate the server */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	printConnectInfo( cryptSession );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, "SVR: Attempt to activate HTTP "
					   "certstore server session", status, __LINE__ );
		cryptDestroySession( cryptSession );
		return( FALSE );
		}

	/* Check whether the session connection is still open */
	status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_CONNECTIONACTIVE,
								&connectionActive );
	if( cryptStatusError( status ) || !connectionActive )
		{
		printExtError( cryptSession, "SVR: Persistent connection has been "
					   "closed, operation", status, __LINE__ );
		return( FALSE );
		}

	/* Activate the connection to handle two more requests */
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, "SVR: Attempt to perform second HTTP "
					   "certstore server transaction", status, __LINE__ );
		cryptDestroySession( cryptSession );
		return( status );
		}
	status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_ACTIVE, TRUE );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptSession, "SVR: Attempt to perform third HTTP "
					   "certstore server transaction", status, __LINE__ );
		cryptDestroySession( cryptSession );
		return( status );
		}

	/* Clean up */
	status = cryptDestroySession( cryptSession );
	if( cryptStatusError( status ) )
		{
		printf( "cryptDestroySession() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	puts( "SVR: HTTP certstore server session succeeded.\n" );
	return( TRUE );
	}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
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 );
	}
Exemplo n.º 28
0
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 );
}
Exemplo n.º 29
0
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;
}
Exemplo n.º 30
0
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);

}