예제 #1
0
X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
       const char *pass, int passlen,
       unsigned char *salt, int saltlen, int iter,
            PKCS8_PRIV_KEY_INFO *p8inf)
{
  X509_SIG *p8 = NULL;
  X509_ALGOR *pbe;

  if (!(p8 = X509_SIG_new())) {
    PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if(pbe_nid == -1) pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
  else pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
  if(!pbe) {
    PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
    goto err;
  }
  X509_ALGOR_free(p8->algor);
  p8->algor = pbe;
  M_ASN1_OCTET_STRING_free(p8->digest);
  p8->digest = PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
          pass, passlen, p8inf, 1);
  if(!p8->digest) {
    PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
    goto err;
  }

  return p8;

  err:
  X509_SIG_free(p8);
  return NULL;
}
예제 #2
0
X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
                         PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe)
{
    X509_SIG *p8;
    ASN1_OCTET_STRING *enckey;

    enckey =
        PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
                                pass, passlen, p8inf, 1);
    if (!enckey) {
        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, PKCS12_R_ENCRYPT_ERROR);
        return NULL;
    }

    if (!(p8 = X509_SIG_new())) {
        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, ERR_R_MALLOC_FAILURE);
        ASN1_OCTET_STRING_free(enckey);
        return NULL;
    }
    X509_ALGOR_free(p8->algor);
    ASN1_OCTET_STRING_free(p8->digest);
    p8->algor = pbe;
    p8->digest = enckey;

    return p8;
}
예제 #3
0
파일: pkcs8.c 프로젝트: RobinWuDev/Qt
X509_SIG *PKCS8_encrypt_pbe(int pbe_nid,
                            const uint8_t *pass_raw, size_t pass_raw_len,
                            uint8_t *salt, size_t salt_len,
                            int iterations, PKCS8_PRIV_KEY_INFO *p8inf) {
  X509_SIG *pkcs8 = NULL;
  X509_ALGOR *pbe;

  pkcs8 = X509_SIG_new();
  if (pkcs8 == NULL) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt_pbe, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  pbe = PKCS5_pbe_set(pbe_nid, iterations, salt, salt_len);
  if (!pbe) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt_pbe, ERR_R_ASN1_LIB);
    goto err;
  }

  X509_ALGOR_free(pkcs8->algor);
  pkcs8->algor = pbe;
  M_ASN1_OCTET_STRING_free(pkcs8->digest);
  pkcs8->digest = pkcs12_item_i2d_encrypt(
      pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass_raw, pass_raw_len, p8inf);
  if (!pkcs8->digest) {
    OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt_pbe, PKCS8_R_ENCRYPT_ERROR);
    goto err;
  }

  return pkcs8;

err:
  X509_SIG_free(pkcs8);
  return NULL;
}
예제 #4
0
PKCS12_MAC_DATA *PKCS12_MAC_DATA_new(void)
{
	PKCS12_MAC_DATA *ret=NULL;
	ASN1_CTX c;
	M_ASN1_New_Malloc(ret, PKCS12_MAC_DATA);
	ret->dinfo = X509_SIG_new();
	ret->salt = M_ASN1_OCTET_STRING_new();
	ret->iter = NULL;
	return(ret);
	M_ASN1_New_Error(ASN1_F_PKCS12_MAC_DATA_NEW);
}
예제 #5
0
bool bdoc::X509Cert::verifySignature(int digestMethod, int digestSize,
		std::vector<unsigned char> digest,
		std::vector<unsigned char> signature)
{
	int result = 0;
	EVP_PKEY* key = getPublicKey();

	switch (EVP_PKEY_type(key->type)) {
	case EVP_PKEY_RSA:
	{
		if (digest.size() > static_cast<size_t>(digestSize)) {
			// The digest already has an ASN.1 DigestInfo header.
			break;
		}
		X509_SIG *sig = X509_SIG_new();
		// Prefer set0 to set_md, so we don't have to initialize the
		// digest lookup table with OpenSSL_add_all_digests. None of
		// our supported digests have parameters anyway.
		X509_ALGOR_set0(sig->algor, OBJ_nid2obj(digestMethod), V_ASN1_NULL, NULL);
		ASN1_OCTET_STRING_set(sig->digest, &digest[0], digest.size());

		unsigned char *asn1 = NULL;
		size_t asn1_len = i2d_X509_SIG(sig, &asn1);
		digest = std::vector<unsigned char>(asn1, asn1 + asn1_len);
		X509_SIG_free(sig);
		break;
	}
	case EVP_PKEY_EC:
	{
		ECDSA_SIG *sig = ECDSA_SIG_new();
		// signature is just r and s concatenated, so split them.
		size_t n_len = signature.size() >> 1;
		BN_bin2bn(&signature[0],     n_len, sig->r);
		BN_bin2bn(&signature[n_len], n_len, sig->s);

		unsigned char *asn1 = NULL;
		size_t asn1_len = i2d_ECDSA_SIG(sig, &asn1);
		signature = std::vector<unsigned char>(asn1, asn1 + asn1_len);
		ECDSA_SIG_free(sig);
		break;
	}
	default:
		THROW_STACK_EXCEPTION("Certificate '%s' has an unsupported "
				"public key type, can not verify signature.",
				getSubject().c_str());
	}

	EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(key, NULL);
	if (!ctx) {
		EVP_PKEY_free(key);
		THROW_STACK_EXCEPTION("Creating signature verification "
				"context failed: %s",
				ERR_reason_error_string(ERR_get_error()));
	}

	if (EVP_PKEY_verify_init(ctx) <= 0) {
		EVP_PKEY_CTX_free(ctx);
		EVP_PKEY_free(key);
		THROW_STACK_EXCEPTION("Initializing signature "
				"verification context failed: %s",
				ERR_reason_error_string(ERR_get_error()));
	}
	result = EVP_PKEY_verify(ctx, &signature[0], signature.size(),
			&digest[0], digest.size());
	if (result < 0) {
		EVP_PKEY_CTX_free(ctx);
		EVP_PKEY_free(key);
		THROW_STACK_EXCEPTION("Error during signature verification: %s",
				ERR_reason_error_string(ERR_get_error()));
	}

	EVP_PKEY_CTX_free(ctx);
	EVP_PKEY_free(key);

	return (result == 1);
}
예제 #6
0
int HSM_PKCS11_rsa_sign ( int type, const unsigned char *m, unsigned int m_len,
	unsigned char *sigret, unsigned int *siglen, const RSA *rsa ) {

	PKCS11_HANDLER *lib = NULL;
	CK_OBJECT_HANDLE *pHandle = NULL;
	HSM *driver = NULL;

	CK_MECHANISM RSA_MECH = { CKM_RSA_PKCS, NULL_PTR, 0 };

	unsigned char *p = NULL;
	unsigned char *s = NULL;
	unsigned char *tmps = NULL;

#if OPENSSL_VERSION_NUMBER < 0x1010000fL
	X509_SIG sig;
	X509_SIG * sig_pnt = &sig;
#else
	X509_SIG * sig_pnt = X509_SIG_new();
#endif

	
	int i, j, rc;

	int keysize = 0;
	CK_ULONG ck_sigsize = 0;

	CK_RV rv = CKR_OK;

	unsigned char *buf = NULL;

	/* Default checks for mis-passed pointers */
	if (!m || !sigret || !siglen || !rsa || !sig_pnt) goto err;

	/* Retrieves the reference to the hsm */
	if((driver = (HSM *) RSA_get_ex_data (rsa, KEYPAIR_DRIVER_HANDLER_IDX))
								== NULL ) {
		PKI_ERROR(PKI_ERR_POINTER_NULL, "Can't get PKCS#11 Driver Handle");
		goto err;
	}

	/* Retrieves the privkey object handler */
	if((pHandle = (CK_OBJECT_HANDLE *) RSA_get_ex_data (rsa, 
				KEYPAIR_PRIVKEY_HANDLER_IDX)) == NULL ) {
		PKI_ERROR(PKI_ERR_POINTER_NULL, "Can't get PrivateKey Handle");
		goto err;
	}

	if ((lib = _hsm_get_pkcs11_handler ( driver )) == NULL ) {
		PKI_ERROR(PKI_ERR_POINTER_NULL, "Can not get PKCS#11 Library handler");
        goto err;
    }

	if(( HSM_PKCS11_session_new( lib->slot_id, &lib->session,
				CKF_SERIAL_SESSION, lib )) == PKI_ERR ) {
		PKI_log_debug("Failed to open a new session (R/W) with the token");
		goto err;
	}

	/* Now we need to check the real encoding */
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
	ASN1_OCTET_STRING digest;
	ASN1_TYPE parameter;
	X509_ALGOR algor;

	sig.algor = &algor;
	if((sig.algor->algorithm = OBJ_nid2obj(type)) == NULL ) {
		PKI_log_debug("HSM_PKCS11_rsa_sign()::Algor not recognized");
		return ( 0 );
	}

	if( algor.algorithm->length == 0 ) {
		PKI_log_debug("HSM_PKCS11_rsa_sign()::Algor length is 0");
		return ( 0 );
	}

	parameter.type = V_ASN1_NULL;
	parameter.value.ptr = NULL;
	sig.algor->parameter = &parameter;

	sig.digest = &digest;
	sig.digest->data = (unsigned char *) m;
	sig.digest->length = (int) m_len;

	i = i2d_X509_SIG(sig_pnt, NULL);

#else
	X509_ALGOR * alg = NULL;
	ASN1_OCTET_STRING * data = NULL;

	// Allocates a new signature
	if ((sig_pnt = X509_SIG_new()) == NULL) goto err;

	// Gets the modifiable algorithm and digest pointers
	X509_SIG_getm(sig_pnt, &alg, &data);

	// Sets the algorithm
	if (!X509_ALGOR_set0(alg, OBJ_nid2obj(type), V_ASN1_NULL, NULL)) goto err;

	// Sets the digest data
	if (!ASN1_OCTET_STRING_set(data, (unsigned char *)m, (int) m_len)) goto err;

	// Gets the size of the DER encoded signature
	i = i2d_X509_SIG(sig_pnt, NULL);
#endif

	if((keysize = RSA_size ( rsa )) == 0 ) {
		PKI_log_debug("HSM_PKCS11_rsa_sign()::KEY size is 0");
		goto err;
	}

	j=RSA_size(rsa);
	if( i > ( j - RSA_PKCS1_PADDING_SIZE )) {
		PKI_log_debug("HSM_PKCS11_rsa_sign()::Digest too big");
		goto err;
	}

	if((tmps = ( unsigned char *) PKI_Malloc ((unsigned int) j + 1 ))
								== NULL ) {
		PKI_log_debug("HSM_PKCS11_rsa_sign()::Memory alloc error!");
		return (0);
	}
	
	p = tmps;
	i2d_X509_SIG(sig_pnt, &p);
	s = tmps;

	rc = pthread_mutex_lock( &lib->pkcs11_mutex );
	PKI_log_debug( "pthread_mutex_lock()::RC=%d", rc );

	while(( rv = lib->callbacks->C_SignInit(lib->session, 
			&RSA_MECH, *pHandle)) == CKR_OPERATION_ACTIVE ) {
		int rc = 0;

		rc = pthread_cond_wait( &lib->pkcs11_cond, &lib->pkcs11_mutex );
		PKI_log_debug( "pthread_cond_wait()::RC=%d", rc );
	}

	if( rv != CKR_OK ) {
		PKI_log_debug("HSM_PKCS11_rsa_sign()::SignInit "
					"(2) failed with code 0x%8.8X", rv );
		pthread_cond_signal( &lib->pkcs11_cond );
		pthread_mutex_unlock( &lib->pkcs11_mutex );

		goto err;
	}

	ck_sigsize = *siglen;
	PKI_log_debug("HSM_PKCS11_rsa_sign()::i = %d, siglen = %d, "
		"sigret = %d (%p)", i, ck_sigsize, sizeof(sigret), sigret );

	/* Let's exagerate for now... */
	buf = PKI_Malloc (RSA_SIGNATURE_MAX_SIZE);
	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );

	ck_sigsize = RSA_SIGNATURE_MAX_SIZE;

	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
	// if((rv = lib->callbacks->C_Sign( lib->session, (CK_BYTE *) m, 
	// 			m_len, sigret, &ck_sigsize)) != CKR_OK ) {
	if((rv = lib->callbacks->C_Sign( lib->session, (CK_BYTE *) s, 
				(CK_ULONG) i, buf, &ck_sigsize)) != CKR_OK ) {
		PKI_log_err("HSM_PKCS11_rsa_sign()::Sign failed with 0x%8.8X",
									rv);
		if( rv == CKR_BUFFER_TOO_SMALL ) {
			/* The sign session has to be terminated */
			/* To Be Done (TBD) */
			PKI_log_err("HSM_PKCS11_rsa_sign()::Buffer too ",
				"small (%s:%d)", __FILE__, __LINE__ );
		}

		pthread_cond_signal( &lib->pkcs11_cond );
		pthread_mutex_unlock( &lib->pkcs11_mutex );

		PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );

		goto err;
	}

	pthread_cond_signal( &lib->pkcs11_cond );
	pthread_mutex_unlock( &lib->pkcs11_mutex );

	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );
	*siglen = (unsigned int) ck_sigsize;
	PKI_log_debug("HSM_PKCS11_rsa_sign():: DEBUG %d", __LINE__ );

	PKI_log_debug("HSM_PKCS11_rsa_sign():: BUF Written = %d", ck_sigsize );
	memcpy(sigret, buf, *siglen);

	// Free allocated memory
	if (tmps) PKI_Free ( tmps );
	if (buf) PKI_Free ( buf );

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
	if (sig_pnt) X509_SIG_free(sig_pnt);
#endif

	// Returns Success (1 is success in OpenSSL)
	return 1;

err:
	// Frees associated memory
	if (tmps) PKI_Free(tmps);
	if (buf) PKI_Free(buf);

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
	if (sig_pnt) X509_SIG_free(sig_pnt);
#endif


	// Returns the error (0 is error in OpenSSL)
	return 0;
}