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; }
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; }
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; }
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); }
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); }
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 = ¶meter; 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; }