Exemple #1
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 #2
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 #3
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 #4
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 #5
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 #6
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 #7
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 #8
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 );
	}