Exemple #1
0
static void updateConfigCert( void )
	{
	CRYPT_CERTIFICATE trustedCert;
	int status;

	/* Import the first certificate, make it trusted, and commit the changes */
	importCertFromTemplate( &trustedCert, CERT_FILE_TEMPLATE, 1 );
	cryptSetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT, TRUE );
	cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CONFIGCHANGED, FALSE );
	cryptDestroyCert( trustedCert );
	cryptEnd();

	/* Do the same with a second certificate.  At the conclusion of this, we 
	   should have two trusted certificates on disk */
	status = cryptInit();
	if( cryptStatusError( status ) )
		{
		puts( "Couldn't reload cryptlib configuration." );
		return;
		}
	importCertFromTemplate( &trustedCert, CERT_FILE_TEMPLATE, 2 );
	cryptSetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT, TRUE );
	cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CONFIGCHANGED, FALSE );
	cryptDestroyCert( trustedCert );
	cryptEnd();
	}
Exemple #2
0
static int add_ca_cert_to_store(CRYPT_KEYSET store, const char *dn, CRYPT_CERTIFICATE cert) {
  int status;
  CRYPT_CERTIFICATE pki_user;

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

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

  status = cryptSetAttribute(pki_user, CRYPT_CERTINFO_CA, 1);
  WARN_AND_RETURN_IF(status);

  status = cryptCAAddItem(store, pki_user);
  WARN_AND_RETURN_IF(status);

  status = cryptDestroyCert(pki_user);
  WARN_AND_RETURN_IF(status);

  status = cryptCAAddItem(store, cert);
  if (!cryptStatusOK(status)) {
    int errorLocus;
    int errorType;

    cryptGetAttribute(store, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus);
    cryptGetAttribute(store, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType);
    fprintf(stderr, "locus %d type %d\n", errorLocus, errorType);
    cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORLOCUS, &errorLocus);
    cryptGetAttribute(cert, CRYPT_ATTRIBUTE_ERRORTYPE, &errorType);
    fprintf(stderr, "locus %d type %d\n", errorLocus, errorType);
  }
  WARN_AND_RETURN_IF(status);

  return CRYPT_OK;
}
Exemple #3
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 );
	}
Exemple #4
0
static int create_selfsigned_cert(CRYPT_CONTEXT ca_key_pair, const char *dn, /* out */ CRYPT_CERTIFICATE *pCert) {
  CRYPT_CERTIFICATE result_certificate;
  int status;

  /* create the certificate and associate it with the CA's pubkey */
  status = cryptCreateCert(&result_certificate, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTIFICATE);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while creating CA selfsigned cert\n", status);
    return status;
  }

  status = cryptSetAttribute(result_certificate, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, ca_key_pair);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while associating CA cert with key\n", status);
    goto err_cert_exit;
  }

  /* set the DN */
  cryptSetAttributeString(result_certificate, CRYPT_CERTINFO_DN, dn, strlen(dn));
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while setting CA cert DN\n", status);
    goto err_cert_exit;
  }

  /* set self-signed and CA bits */
  status = cryptSetAttribute(result_certificate, CRYPT_CERTINFO_SELFSIGNED, 1);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while setting CA cert selfsigned bit\n", status);
    goto err_cert_exit;
  }

  status = cryptSetAttribute(result_certificate, CRYPT_CERTINFO_CA, 1);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while setting CA cert CA bit\n", status);
    goto err_cert_exit;
  }

  /* set implicit trust bit */
  status = cryptSetAttribute(result_certificate, CRYPT_CERTINFO_TRUSTED_USAGE, CRYPT_KEYUSAGE_KEYCERTSIGN | CRYPT_KEYUSAGE_CRLSIGN);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while setting CA cert implicit trust bit\n", status);
    goto err_cert_exit;
  }

  /* sign it */
  status = cryptSignCert(result_certificate, ca_key_pair);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while self-signing CA cert\n", status);
    goto err_cert_exit;
  }

  *pCert = result_certificate; return CRYPT_OK;
err_cert_exit:
  cryptDestroyCert(result_certificate); return status;
}
Exemple #5
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;
}
unsigned __stdcall encTest( void *arg ) 
	{
	CRYPT_ENVELOPE cryptEnvelope;
	CRYPT_CERTIFICATE cryptCert;
	BYTE buffer[ 1024 ];
	const int count = *( ( int * ) arg );
	int bytesCopied, i, status;

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

	for( i = 0; i < count; i++ ) 
		{
		FILE *filePtr;
		int certSize;

		if( ( filePtr = fopen( "testdata/cert5.der", "rb" ) ) != NULL ) 
			{
			certSize = fread( buffer, 1, 1024, filePtr );
			fclose( filePtr );
			}

		status = cryptImportCert( buffer, certSize, CRYPT_UNUSED, 
								  &certificate );
		if( cryptStatusOK( status ) )
			status = cryptCreateEnvelope( &cryptEnvelope, CRYPT_UNUSED, 
										  CRYPT_FORMAT_CMS );
		if( cryptStatusOK( status ) )
			status = cryptSetAttribute( cryptEnvelope, 
										CRYPT_ENVINFO_PUBLICKEY, cryptCert );
		if( cryptStatusOK( status ) )
			status = cryptPushData( cryptEnvelope, buffer, 200, 
									&bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptFlushData( cryptEnvelope );
		if( cryptStatusOK( status ) )
			status = cryptPopData( cryptEnvelope, buffer, 1024, 
								   &bytesCopied );
		if( cryptStatusOK( status ) )
			status = cryptDestroyCert( cryptCert );
		if( cryptStatusOK( status ) )
			status = cryptDestroyEnvelope( cryptEnvelope );
		if( cryptStatusError( status ) )
			{
			_endthreadex( status );
			return( 0 );
			}
		}

	_endthreadex( 0 );
	return( 0 );
	}
Exemple #7
0
static int connectOCSPDirect( void )
	{
	CRYPT_CERTIFICATE cryptCert;
	CRYPT_SESSION cryptSession;
	int status;

	printf( "Testing direct OCSP query...\n" );

	/* Get the EE certificate */
	status = importCertFromTemplate( &cryptCert, OCSP_EEOK_FILE_TEMPLATE,
									 OCSP_SERVER_NO );
	if( cryptStatusError( status ) )
		{
		printf( "EE cryptImportCert() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Create the OCSP session and add the server URL */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
								 CRYPT_SESSION_OCSP );
	if( status == CRYPT_ERROR_PARAM3 )	/* OCSP session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
#ifdef OCSP_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 */

	/* Check the certificate directly against the server.  This check 
	   quantises the result into a basic pass/fail that doesn't provide as 
	   much detail as the low-level OCSP check, so it's not unusual to get
	   CRYPT_ERROR_INVALID whent he low-level check returns
	   CRYPT_OCSPSTATUS_UNKNOWN */
	status = cryptCheckCert( cryptCert, cryptSession );
	printf( "Certificate status check returned %d.\n", status );

	/* Clean up */
	cryptDestroyCert( cryptCert );
	cryptDestroySession( cryptSession );

	puts( "OCSP direct query succeeded.\n" );
	return( TRUE );
	}
Exemple #8
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;

}
Exemple #9
0
static int connectRTCSDirect( void )
	{
	CRYPT_CERTIFICATE cryptCert;
	CRYPT_SESSION cryptSession;
	int status;

	printf( "Testing direct RTCS query...\n" );

	/* Get the EE certificate */
	status = importCertFromTemplate( &cryptCert, RTCS_FILE_TEMPLATE,
									 RTCS_SERVER_NO );
	if( cryptStatusError( status ) )
		{
		printf( "EE cryptImportCert() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Create the RTCS session and add the server URL */
	status = cryptCreateSession( &cryptSession, CRYPT_UNUSED,
								 CRYPT_SESSION_RTCS );
	if( status == CRYPT_ERROR_PARAM3 )	/* RTCS session access not available */
		return( CRYPT_ERROR_NOTAVAIL );
#ifdef RTCS_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 */

	/* Check the certificate directly against the server */
	status = cryptCheckCert( cryptCert, cryptSession );
	printf( "Certificate status check returned %d.\n", status );

	/* Clean up */
	cryptDestroyCert( cryptCert );
	cryptDestroySession( cryptSession );

	puts( "RTCS direct query succeeded.\n" );
	return( TRUE );
	}
Exemple #10
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;
}
Exemple #11
0
static int fuzzFile( const char *fuzzFileName )
	{
	CRYPT_CERTIFICATE cryptCert;
	BYTE buffer[ 4096 ];
	int length, status;

	/* Read the data to fuzz */
	length = readFileData( fuzzFileName, fuzzFileName, buffer, 4096, 64, 
						   TRUE );
	if( length < 64 )
		return( CRYPT_ERROR_READ );

	/* Process the input file */
	status = cryptImportCert( buffer, length, CRYPT_UNUSED, &cryptCert );
	if( cryptStatusOK( status ) )
		cryptDestroyCert( cryptCert );

	return( CRYPT_OK );
	}
Exemple #12
0
void testSystemSpecific2( void )
	{
	CRYPT_CERTIFICATE cryptCert;
	const time_t theTime = time( NULL ) - 5;
	int status;

	/* Make sure that the cryptlib and non-cryptlib code use the same time_t
	   size (some systems are moving from 32- to 64-bit time_t, which can 
	   lead to problems if the library and calling code are built with 
	   different sizes) */
	status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
							  CRYPT_CERTTYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		{
		if( status == CRYPT_ERROR_NOTAVAIL )
			{
			puts( "Couldn't create certificate object for time sanity-check "
				  "because certificate\n" "use has been disabled, skipping "
				  "time sanity check...\n" );
			return;
			}
		puts( "Couldn't create certificate object for time sanity-check." );
		exit( EXIT_FAILURE );
		}
	status = cryptSetAttributeString( cryptCert, CRYPT_CERTINFO_VALIDFROM,
									  &theTime, sizeof( time_t ) );
	cryptDestroyCert( cryptCert );
	if( status == CRYPT_ERROR_PARAM4 )
		{
		printf( "Warning: This compiler is using a %ld-bit time_t data type, "
				"which appears to be\n         different to the one that "
				"was used when cryptlib was built.  This\n         situation "
				"usually occurs when the compiler allows the use of both\n"
				"         32- and 64-bit time_t data types and different "
				"options were\n         selected for building cryptlib and "
				"the test app.  To resolve this,\n         ensure that both "
				"cryptlib and the code that calls it use the same\n"
				"         time_t data type.\n", 
				( long ) sizeof( time_t ) * 8 );
		exit( EXIT_FAILURE );
		}
	}
Exemple #13
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;
}
Exemple #14
0
void show_import_request_dialog(FRONTEND * fe) {
    /* import dialog -> dialog (OK, cancel), filename entry & browse */
    GtkWidget *dlg;
    GtkEntry *filename_entry;
    GtkButton *browse_button;
    GtkBox *box;
    int status;
    gint result;

    dlg =
        gtk_dialog_new_with_buttons("Import Request",
                                    GTK_WINDOW(fe->mainWindow),
                                    GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT,
                                    GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
                                    GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
    box = GTK_BOX(gtk_hbox_new(0, 5));

    gtk_box_pack_start(box, gtk_label_new("Import from"), FALSE, FALSE, 0);
    filename_entry = GTK_ENTRY(gtk_entry_new());
    gtk_box_pack_start(box, GTK_WIDGET(filename_entry), FALSE, FALSE, 0);
    browse_button = GTK_BUTTON(gtk_button_new_with_mnemonic("_Browse..."));
    gtk_box_pack_start(box, GTK_WIDGET(browse_button), FALSE, FALSE, 0);
    g_signal_connect(G_OBJECT(browse_button), "clicked",
                     G_CALLBACK(on_browse_button_clicked), dlg);
    g_object_set_data_full(G_OBJECT(browse_button), "entry", filename_entry, NULL);     /* don't ref the entry -- same lifetime */
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), GTK_WIDGET(box), FALSE,
                       FALSE, 0);

    gtk_widget_show_all(GTK_WIDGET(GTK_DIALOG(dlg)->vbox));
    result = gtk_dialog_run(GTK_DIALOG(dlg));
    if (result == GTK_RESPONSE_ACCEPT) {
        CRYPT_CERTIFICATE request;
        gchar *filename;

        filename =
            g_filename_from_utf8(gtk_entry_get_text(filename_entry), -1, NULL,
                                 NULL, NULL);
        if (filename != NULL) {
            void *data;
            int data_len;
            data = lmz_file_read_full(filename, &data_len);
            if (data != NULL) {
                status =
                    cryptImportCert(data, data_len, CRYPT_UNUSED, &request);
                if (cryptStatusOK(status)) {
                    int id;
                    status = lmz_ca_add_request(fe->db, request, &id);
                    if (!cryptStatusOK(status)) {
                        show_error_dialog(NULL,
                                          "error adding request to db (cl err %d)",
                                          status);
                    }
                    else {
                        /* yay, it worked */
                        GtkTreeView *mainwin_req_tv, *mainwin_cert_tv;
                        mainwin_req_tv =
                            GTK_TREE_VIEW(g_object_get_data
                                          (G_OBJECT(fe->mainWindow),
                                           "request-list"));
                        mainwin_cert_tv =
                            GTK_TREE_VIEW(g_object_get_data
                                          (G_OBJECT(fe->mainWindow),
                                           "certificate-list"));
                        refresh_request_tree_view(mainwin_req_tv, fe);
                        refresh_cert_tree_view(mainwin_cert_tv, fe);
                    }
                    cryptDestroyCert(request);
                }
                else {
                    show_error_dialog(NULL,
                                      "error importing request (cl err %d)",
                                      status);
                }
                free(data);
            }
            else {
                show_error_dialog(NULL, "error reading file");
            }
            g_free(filename);
        }
        else {
        }
    }
    gtk_widget_destroy(dlg);
}
Exemple #15
0
int testReadCert( void )
	{
	CRYPT_CERTIFICATE cryptCert;
	C_CHR name[ CRYPT_MAX_TEXTSIZE + 1 ], email[ CRYPT_MAX_TEXTSIZE + 1 ];
	C_CHR filenameBuffer[ FILENAME_BUFFER_SIZE ];
	int length, status;

	/* Get the DN from one of the test certs (the one that we wrote to the
	   keyset earlier with testKeysetWrite() */
	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 );
		}
	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 = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_EMAIL,
										  email, &length );
		}
	if( cryptStatusOK( status ) )
		{
		int i;

#ifdef UNICODE_STRINGS
		length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
		email[ length ] = TEXT( '\0' );

		/* Mess up the case to make sure that case-insensitive matching is
		   working */
		for( i = 0; i < length; i++ )
			{
			if( i & 1 )
				email[ i ] = toupper( email[ i ] );
			else
				email[ i ] = tolower( email[ i ] );
			}
		}
	else
		{
		return( extErrorExit( cryptCert, "cryptGetAttributeString()", status,
							  __LINE__ ) );
		}
	cryptDestroyCert( cryptCert );

	puts( "Testing certificate database read..." );
	status = testKeysetRead( DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME,
	 						 CRYPT_KEYID_NAME, name,
							 CRYPT_CERTTYPE_CERTIFICATE,
							 READ_OPTION_NORMAL );
	if( status == CRYPT_ERROR_NOTAVAIL )
		{
		/* Database keyset access not available */
		return( CRYPT_ERROR_NOTAVAIL );
		}
	if( status == CRYPT_ERROR_FAILED )
		{
		puts( "This is probably because you haven't set up a database or "
			  "data source for use\nas a key database.  For this test to "
			  "work, you need to set up a database/data\nsource with the "
			  "name '" DATABASE_KEYSET_NAME_ASCII "'.\n" );
		return( TRUE );
		}
	if( !status )
		return( FALSE );
	puts( "Reading certs using cached query." );
	status = testKeysetRead( DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME,
	 						 CRYPT_KEYID_EMAIL, email,
							 CRYPT_CERTTYPE_CERTIFICATE,
							 READ_OPTION_MULTIPLE );
	if( !status )
		return( FALSE );

	/* Get the DN from one of the test certificate chains */
	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 = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_COMMONNAME,
									  name, &length );
	if( cryptStatusOK( status ) )
		{
#ifdef UNICODE_STRINGS
		length /= sizeof( wchar_t );
#endif /* UNICODE_STRINGS */
		name[ length ] = TEXT( '\0' );
		}
	cryptDestroyCert( cryptCert );

	/* Now read the complete certificate chain */
	puts( "Reading complete certificate chain." );
	status = testKeysetRead( DATABASE_KEYSET_TYPE, DATABASE_KEYSET_NAME,
	 						 CRYPT_KEYID_NAME, name,
							 CRYPT_CERTTYPE_CERTCHAIN, READ_OPTION_NORMAL );
	if( !status )
		return( FALSE );
	puts( "Certificate database read succeeded.\n" );
	return( TRUE );
	}
Exemple #16
0
void createCSR(CRYPT_CONTEXT keyContext) {
  CRYPT_CERTIFICATE cryptCertRequest;
  void *certRequest;
  int certRequestMaxLength, certRequestLength;
  FILE *f = NULL;
  int status;
  
  /* Create a certification request and add the public key to it */
  status = cryptCreateCert( &cryptCertRequest, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTREQUEST );
  if (status != CRYPT_OK) {
    fprintf(stderr, "Error creating certRequest\n");
    exit(1);
  }
  status = cryptSetAttribute( cryptCertRequest, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, keyContext );
  if (status != CRYPT_OK) {
    fprintf(stderr, "Error setting pubkey: %d\n", status);
    exit(1);
  }
  /* Add identification information */
  
  status = cryptSetAttributeString(cryptCertRequest, CRYPT_CERTINFO_COUNTRYNAME, "US", 2);
  if (status != CRYPT_OK) {
    fprintf(stderr, "Error setting C\n");
    exit(1);
  }
  status = cryptSetAttributeString(cryptCertRequest, CRYPT_CERTINFO_ORGANIZATIONNAME, "example", 7);
  if (status != CRYPT_OK) {
    fprintf(stderr, "Error setting O\n");
    exit(1);
  }
  status = cryptSetAttributeString(cryptCertRequest, CRYPT_CERTINFO_COMMONNAME, "example", 7);
  if (status != CRYPT_OK) {
    fprintf(stderr, "Error setting CN\n");
    exit(1);
  }
  /* Sign the certification request with the private key and export it
  */
  status = cryptSignCert( cryptCertRequest, keyContext );
  if (status != CRYPT_OK) {
    fprintf(stderr, "Error signing CSR\n");
    exit(1);
  }
  status = cryptExportCert( NULL, 0, &certRequestMaxLength, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cryptCertRequest );
  if (status != CRYPT_OK) {
    fprintf(stderr, "Error getting max cert length\n");
    exit(1);
  }
  certRequest = malloc( certRequestMaxLength );
  status = cryptExportCert( certRequest, certRequestMaxLength, &certRequestLength, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cryptCertRequest);
  if (status != CRYPT_OK) {
    fprintf(stderr, "Error exporting cert\n");
    exit(1);
  }
  /* Destroy the certification request */
  status = cryptDestroyCert( cryptCertRequest );
  if (status != CRYPT_OK) {
    fprintf(stderr, "Error destroying cert request\n");
    exit(1);
  }
  
  f = fopen(CSR_FILE, "w");
  if (!f) { perror("fopen CSR_FILE"); exit(1); }
  fwrite(certRequest, certRequestLength, 1, f);
  fclose(f);
  free(certRequest);
}
Exemple #17
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 );
	}
Exemple #18
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 );
	}
Exemple #19
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 );
	}
Exemple #20
0
void show_export_crl_dialog(FRONTEND * fe) {
    /* export dialog -> 
     * dialog (OK, cancel), 
     * filename entry & browse, 
     * format choice (DER, text)
     */
    GtkWidget *dlg;
    GtkEntry *filename_entry;
    GtkButton *browse_button;
    GtkRadioButton *rb_text, *rb_der;
    GtkBox *box;
    gint result;

    dlg =
        gtk_dialog_new_with_buttons("Export CRL", GTK_WINDOW(fe->mainWindow),
                                    GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT,
                                    GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
                                    GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
    box = GTK_BOX(gtk_hbox_new(0, 5));

    gtk_box_pack_start(box, gtk_label_new("Export to"), FALSE, FALSE, 0);
    filename_entry = GTK_ENTRY(gtk_entry_new());
    gtk_box_pack_start(box, GTK_WIDGET(filename_entry), FALSE, FALSE, 0);
    browse_button = GTK_BUTTON(gtk_button_new_with_mnemonic("_Browse..."));
    gtk_box_pack_start(box, GTK_WIDGET(browse_button), FALSE, FALSE, 0);
    g_signal_connect(G_OBJECT(browse_button), "clicked",
                     G_CALLBACK(on_browse_button_clicked), dlg);
    /* don't ref the entry -- same lifetime */
    g_object_set_data_full(G_OBJECT(browse_button), "entry", filename_entry, NULL);     
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), GTK_WIDGET(box), FALSE,
                       FALSE, 0);

    rb_der =
        GTK_RADIO_BUTTON(gtk_radio_button_new_with_mnemonic
                         (NULL, "_DER (Binary)"));
    rb_text =
        GTK_RADIO_BUTTON(gtk_radio_button_new_with_mnemonic_from_widget
                         (rb_der, "_PEM (Text)"));
    box = GTK_BOX(gtk_hbox_new(0, 5));
    gtk_box_pack_start(box, gtk_label_new("Format:"), FALSE, FALSE, 0);
    gtk_box_pack_start(box, GTK_WIDGET(rb_der), FALSE, FALSE, 0);
    gtk_box_pack_start(box, GTK_WIDGET(rb_text), FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), GTK_WIDGET(box), FALSE,
                       FALSE, 0);

    gtk_widget_show_all(GTK_WIDGET(GTK_DIALOG(dlg)->vbox));
    result = gtk_dialog_run(GTK_DIALOG(dlg));
    if (result == GTK_RESPONSE_ACCEPT) {
        void *buf;
        int status;
        int len;
        gboolean text_format;
        CRYPT_CERTFORMAT_TYPE fmt;
        FILE *f;
        gchar *filename;
        CRYPT_CERTIFICATE crl;
        CRYPT_CONTEXT key;
        gchar *password;
        /* get password */
        password = do_get_password(GTK_WINDOW(dlg));
        if (password == NULL) {
            /* cancelled? */
            goto cleanup;
        }
        /* sign */
        status = lmz_ca_get_signing_key(fe->db, password, &key);
        g_free(password); /* dynamic */
        if (status == CRYPT_ERROR_WRONGKEY) {
            show_error_dialog(GTK_WINDOW(dlg), "Wrong password");
            goto cleanup;
        }
        else if (!cryptStatusOK(status)) {
            show_error_dialog(GTK_WINDOW(dlg),
                              "Error getting signing key (cryptlib error %d)",
                              status);
            goto cleanup;
        }
        status = lmz_ca_gen_crl(fe->db, &crl);
        if (cryptStatusOK(status)) {
            /* sign it */
            status = cryptSignCert(crl, key);
            if (cryptStatusOK(status)) {
                text_format =
                    gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rb_text));
                fmt =
                    text_format ? CRYPT_CERTFORMAT_TEXT_CERTIFICATE :
                    CRYPT_CERTFORMAT_CERTIFICATE;
                status = cryptExportCert(NULL, 0, &len, fmt, crl);
                buf = malloc(len);
                status = cryptExportCert(buf, len, &len, fmt, crl);
                if (cryptStatusOK(status)) {
                    filename =
                        g_filename_from_utf8(gtk_entry_get_text(filename_entry),
                                             -1, NULL, NULL, NULL);
                    if (filename != NULL) {
                        f = fopen(filename, "w");
                        if (f != NULL) {
                            if (fwrite(buf, len, 1, f) != 1) {
                                show_error_dialog(NULL,
                                                  "error fully writing data");
                            }
                            fclose(f);
                        }
                        else {
                            show_error_dialog(NULL,
                                              "error opening file for writing");
                        }
                        g_free(filename);
                    }
                    else {
                        show_error_dialog(NULL, "filename conversion error");
                    }
                    free(buf);
                }
            }
            else {
                show_error_dialog(NULL, "error signing crl (cl error %d)",
                                  status);
            }
            cryptDestroyCert(crl);
        }
        else {
            show_error_dialog(NULL, "error generating crl (cl error %d)",
                              status);
        }
        cryptDestroyContext(key);
    }
  cleanup:
    gtk_widget_destroy(dlg);
}
Exemple #21
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 );
	}
Exemple #22
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;
}
Exemple #23
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;
}
int funcion6()
{

	int valido, tamFirma, tam, tamCert, i, status, keySize, keyMaxSize;
	long opcion_l;
	char opcion[5], *ptr, *endptr, *buffer, *rutaToCheck, *rutaFirma, *nombreFirma, *firma, *cert, *nombreCert, *rutaCert;
	FILE *ptrFileToCheck, *ptrFirma, *ptrCert;
	DIR *dir;	
	struct dirent *ent;
	struct stat st;

	/*Reservo memoria*/
	rutaToCheck=(char *)malloc(120);
	rutaFirma=(char *)malloc(120);
	nombreFirma=(char *)malloc(50);
	nombreCert=(char *)malloc(50);
	rutaCert=(char *)malloc(120);

	system("clear");
	printf("\n ------------------------------------\n");
	printf("|          Verificar firma           |\n");
	printf(" ------------------------------------\n\n");
	fflush(stdout);

	/*PASO 1. Ruta del archivo a verificar*/
	do {
		valido=0;
		printf("PASO 1. Introduzca la ruta del archivo que desea verificar: ");
		scanf("%s", rutaToCheck);
		if((ptrFileToCheck=fopen(rutaToCheck, "rb")) == NULL ) {
			printf("No se encuentra el archivo. Revise la ruta :)\n\n");
			valido=1;
			fflush(stdout);
		} 
	} while(valido==1);
	

	/*Necesitamos abrir el archivo y volcarlo a memoria*/
	stat(rutaToCheck, &st);
	tam=st.st_size;
	buffer=(char *)malloc(tam);
	fread(buffer, 1, tam, ptrFileToCheck);


	/*Buscamos el caracter '/' dentro de la cadena. Si está, es porque el usuario metió la ruta completa*/
	if((ptr=(strrchr(rutaToCheck, '/')))!=NULL) sprintf(nombreFirma, "%s.p7s", ptr+1); //Ruta completa
	else sprintf(nombreFirma, "%s.p7s", rutaToCheck); //El usuario metió el nombre del archivo

	/*Ahora tengo que leer la firma. Primero la busco, y si no está, que la seleccione el usuario*/
	dir = opendir ("./Firmas digitales/");
	if (dir != NULL) {
		i=0;
		/* Vamos a buscar los archivos .p7s que correspondan*/
	  	while ((ent = readdir (dir)) != NULL) {
			if((ptr=strstr(ent->d_name, nombreFirma))!=NULL) { 
				i++;
			}
		}
		closedir(dir);
	} else {
	  	/* Problemas al abrir el directorio */
	  	printf("¿Ha ejecutado ya la opción 5?\n");
		fflush(stdout);
	  	return(-1);
	}

	if(i==0) { //Resultados = 0
		printf("\nNo se ha encontrado una firma adecuada\n");
		fflush(stdout);
		printf("Seleccione cuál de los siguientes archivos corresponde con la firma creada en la función 5:\n ");
		fflush(stdout);
		dir = opendir ("./Firmas digitales/");	
		/* 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, ".p7s"))!=NULL) {
				i++; 
				printf("  %d. %s\n", i, ent->d_name);
			}
		}
		closedir(dir);
		/*El usuario introduce el número que corresponde a la firma que elija*/
		do{
			valido=0;
			printf("Introduzca el número de la firma que desea usar >> ");
			scanf("%s", &opcion);
			opcion_l = strtol(opcion,&endptr,10);
			if(strlen(endptr)!=0 || opcion_l < 1 || opcion_l > 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 ("./Firmas digitales/");
		i=0;
	 	while ((ent = readdir (dir)) != NULL) {
			if((ptr=strstr(ent->d_name, ".p7s"))!=NULL) {
				i++;
				if(opcion_l==i) { 
					sprintf(rutaFirma, "./Firmas digitales/%s", ent->d_name);
				}	
			}
		}
		closedir(dir);
		
	} else if(i==1) {
		printf("\n-> Se ha encontrado 1 firma adecuada. Se usará la firma %s por defecto\n\n", nombreFirma);
		fflush(stdout);
		sprintf(rutaFirma, "./Firmas digitales/%s", nombreFirma);
	} 

	/*Abrimos la firma*/
	if((ptrFirma=fopen(rutaFirma, "rb")) < 0) {
		printf("Error al crear el archivo\n");
		fflush(stdout);
		return(-1);
	}
	stat(rutaFirma, &st);
	tamFirma=st.st_size;
	firma=(char *)malloc(tamFirma);
	fread(firma, 1, tamFirma, ptrFirma);

	/*Ahora necesitamos el certificado*/
	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.*/
	  	while ((ent = readdir (dir)) != NULL) {
			if((ptr=strstr(ent->d_name, ".cert"))!=NULL) { 
				strcpy(nombreCert, 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("No se ha encontrado ningún certificado. (¿Ha ejecutado ya la opción 1?)\n");
		fflush(stdout);
		return(-1);
	} else if(i==1) {
		printf("\n-> Se ha encontrado 1 certificado. Se usará el certificado %s por defecto\n\n", nombreCert);
		fflush(stdout);
		sprintf(rutaCert, "./Claves y certificados/%s", nombreCert);
	} else {
		printf("\n¡¡Hay %d certificados creados !!\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.*/
	  	while ((ent = readdir (dir)) != NULL) {
			if((ptr=strstr(ent->d_name, ".cert"))!=NULL) {
				i++; 
				printf("  %d. %s\n", i, ent->d_name);
			}
		}
		closedir(dir);
	
		do{
			valido=0;
			printf("Introduzca el número del certificado que desea usar >> ");
			scanf("%s", &opcion);
			opcion_l = strtol(opcion,&endptr,10);
			if(strlen(endptr)!=0 || opcion_l < 1 || opcion_l > 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 rutaCert*/
		dir = opendir ("./Claves y certificados/");
		i=0;
	 	while ((ent = readdir (dir)) != NULL) {
			if((ptr=strstr(ent->d_name, ".cert"))!=NULL) {
				i++;
				if(opcion_l==i) { 
					sprintf(rutaCert, "./Claves y certificados/%s", ent->d_name);
				}	
			}
		}
		closedir(dir);
	}
	ptrCert=fopen(rutaCert, "rb");
	stat(rutaCert, &st);
	tamCert=st.st_size;
	cert=(char *)malloc(tamCert);
	fread(cert, 1, tamCert, ptrCert);

	/*Importamos certificado*/
	/*Creo el contexto para el hash*/
	CRYPT_CONTEXT contextoHash;
	if((status=cryptCreateContext(&contextoHash, CRYPT_UNUSED, CRYPT_ALGO_SHA1))!=CRYPT_OK) {
		printf("Error al crear el contexto. Código %d\n", status);
		fflush(stdout);
		return(-1);
	}

	/*Hash*/
	if((status=cryptEncrypt(contextoHash, buffer, tam))!=CRYPT_OK) {
		printf("Error al calcular el hash. Código %d\n", status);
		fflush(stdout);
		return(-1);
	}
	if((status=cryptEncrypt(contextoHash, buffer, 0))!=CRYPT_OK) {
		printf("Error al calcular el hash. Código %d\n", status);
		fflush(stdout);
		return(-1);
	}

	CRYPT_CERTIFICATE certificado;
	if((status=cryptImportCert(cert, tamCert, CRYPT_UNUSED, &certificado))!=CRYPT_OK) {
		printf("Error al importar el certificado. Código %d\n", status);
		fflush(stdout);
		return(-1);	
	}
	if((status=cryptCheckSignature(firma, tamFirma, certificado, contextoHash))!=CRYPT_OK) {
		printf("La firma no concuerda. Código %d\n", status);
		fflush(stdout);
		return(-1);	
	}

	/*Destruimos contextos y cerramos lo necesario*/
	if((status=cryptDestroyContext(contextoHash))!=CRYPT_OK) {
		printf("Error al destruir el contexto. Código %d\n", status);
		fflush(stdout);
		return(-1);
	}
	if((status=cryptDestroyCert(certificado))!=CRYPT_OK) {
		printf("Error al destruir el certificado. Código %d\n", status);
		fflush(stdout);
		return(-1);	
	}
	return(0);

}
Exemple #25
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 );
	}
Exemple #26
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 );
}
Exemple #27
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;
}
Exemple #28
0
static int exec_create(int argc, char **argv) {
  CRYPT_KEYSET keyset;
  CRYPT_CERTIFICATE cert;
  CRYPT_CONTEXT context;
  int status;
  const char *filename = argv[0];
  char keyfilename[4096]; /* PATH_MAX */
  char certfilename[4096]; /* PATH_MAX */

  /* create the tables using cryptlib */
  status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, filename, CRYPT_KEYOPT_CREATE);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while opening keyset\n", status);
    return 1;
  }
  status = cryptKeysetClose(keyset);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while closing keyset\n", status);
    return 1;
  }
  if (opt_verbose) fprintf(stdout, "file %s created OK as cert keyset store\n", filename);

  /* the database has been created, but there is still no CA key
   * and CA cert -- now we generate it and put the CA key in a file
   * and import the public key & cert into the db.
   */
  status = create_keypair(&context, DEFAULT_CA_PRIVKEY_LABEL);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while generating CA keypair\n", status);
    return 1;
  }
  /* generate cert */
  status = create_selfsigned_cert(context, DEFAULT_DN, &cert);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while generating CA cert\n", status);
    goto err_ctx_exit;
  }
  snprintf(keyfilename, 4095, "%s.keys", filename);
  status = save_ca_keypair_and_cert_to_file(context, cert, keyfilename, DEFAULT_PASSWORD); /* TODO password */
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while saving CA keypair to %s\n", status, keyfilename);
    goto err_ctx_exit;
  }
  if (opt_verbose) fprintf(stdout, "CA keys saved to file keyset %s\n", filename);


  /* save it */
  snprintf(certfilename, 4095, "%s.ca.crt", filename);
  status = export_cert(cert, certfilename);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while saving CA cert\n", status);
    goto err_cert_exit;
  }

#if 0
  /* add to store */
  status = cryptKeysetOpen(&keyset, CRYPT_UNUSED, CRYPT_KEYSET_DATABASE_STORE, filename, CRYPT_KEYOPT_NONE);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while opening CA cert store to save CA cert\n", status);
    goto err_cert_exit;
  }


  status = add_ca_cert_to_store(keyset, DEFAULT_DN, cert);
  /* status = cryptCAAddItem(keyset, cert); */
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while saving CA cert to CA cert store\n", status);
    cryptKeysetClose(keyset);
    goto err_cert_exit;
  }
  status = cryptKeysetClose(keyset);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while closing CA cert store\n", status);
    goto err_cert_exit;
  }
  if (opt_verbose) fprintf(stdout, "CA certs for %s saved to %s\n", DEFAULT_DN, filename);
#endif

  /* cleanup */
  status = cryptDestroyCert(cert);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while destroying CA cert\n", status);
    goto err_ctx_exit;
  }
  status = cryptDestroyContext(context);
  if (!cryptStatusOK(status)) {
    fprintf(stderr, "cryptlib error %d while destroying CA keypair context\n", status);
    /* NO ERROR CASE */
    return 1;
  }

  return 0;

err_cert_exit:
  cryptDestroyCert(cert);
err_ctx_exit:
  cryptDestroyContext(context);
  return 1;
}
Exemple #29
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;
}
Exemple #30
0
static int generateKey( const int keyBits, const char *certRequestFileName )
	{
	CRYPT_KEYSET cryptKeyset;
	CRYPT_CERTIFICATE cryptCertRequest;
	CRYPT_CONTEXT cryptKey;
	FILE *filePtr;
	BYTE certBuffer[ BUFFER_SIZE ];
	char filenameBuffer[ FILENAME_BUFFER_SIZE ];
	void *fileNamePtr = filenameBuffer;
	int length, count, status;

	/* Generate a key to certify.  We can't just reuse the built-in test key
	   because this has already been used as the CA key and the keyset code
	   won't allow it to be added to a keyset as both a CA key and user key,
	   so we have to generate a new one */
	status = cryptCreateContext( &cryptKey, CRYPT_UNUSED, CRYPT_ALGO_ECDSA );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( cryptKey, CRYPT_CTXINFO_KEYSIZE, 
									keyBits >> 3 );
	if( cryptStatusOK( status ) )
		{
		status = cryptSetAttributeString( cryptKey, CRYPT_CTXINFO_LABEL,
										  USER_PRIVKEY_LABEL,
										  paramStrlen( USER_PRIVKEY_LABEL ) );
		}
	if( cryptStatusOK( status ) )
		status = cryptGenerateKey( cryptKey );
	if( cryptStatusError( status ) )
		{
		printf( "Key generation failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}

	/* Create the certificate request for the new key */
	status = cryptCreateCert( &cryptCertRequest, CRYPT_UNUSED,
							  CRYPT_CERTTYPE_CERTREQUEST );
	if( cryptStatusOK( status ) )
		status = cryptSetAttribute( cryptCertRequest,
					CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cryptKey );
	if( cryptStatusOK( status ) && \
		!addCertFields( cryptCertRequest, certRequestData, __LINE__ ) )
		return( FALSE );
	if( cryptStatusOK( status ) )
		status = cryptSignCert( cryptCertRequest, cryptKey );
	if( cryptStatusOK( status ) )
		{
		status = cryptExportCert( certBuffer, BUFFER_SIZE, &length,
								  CRYPT_CERTFORMAT_CERTIFICATE, 
								  cryptCertRequest );
		cryptDestroyCert( cryptCertRequest );
		}
	if( cryptStatusError( status ) )
		{
		printf( "Certificate request creation failed with error code %d, "
				"line %d.\n", status, __LINE__ );
		return( FALSE );
		}
	if( ( filePtr = fopen( certRequestFileName, "wb" ) ) != NULL )
		{
		count = fwrite( certBuffer, 1, length, filePtr );
		fclose( filePtr );
		}
	if( filePtr == NULL || count < length )
		{
		printf( "Couldn't write certificate request to disk, line %d.\n", 
				__LINE__ );
		return( FALSE );
		}

	/* Create the keyset and add the private key to it */
	filenameFromTemplate( filenameBuffer, SERVER_ECPRIVKEY_FILE_TEMPLATE, 
						  keyBits );
	status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
							  fileNamePtr, CRYPT_KEYOPT_CREATE );
	if( cryptStatusError( status ) )
		{
		printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
				status, __LINE__ );
		return( FALSE );
		}
	status = cryptAddPrivateKey( cryptKeyset, cryptKey,
								 TEST_PRIVKEY_PASSWORD );
	if( cryptStatusError( status ) )
		{
		printExtError( cryptKeyset, "cryptAddPrivateKey()", status, 
					   __LINE__ );
		return( FALSE );
		}
	cryptDestroyContext( cryptKey );
	cryptKeysetClose( cryptKeyset );

	return( TRUE );
	}