static int rsa_eay_blinding(RSA *rsa, BN_CTX *ctx) { int ret = 1; /* Check again inside the lock - the macro's check is racey */ if(rsa->blinding == NULL) ret = RSA_blinding_on(rsa, ctx); return ret; }
Key * key_load_private_pem(int fd, int type, const char *passphrase, char **commentp) { FILE *fp; EVP_PKEY *pk = NULL; Key *prv = NULL; char *name = "<no key>"; fp = fdopen(fd, "r"); if (fp == NULL) { error("fdopen failed: %s", strerror(errno)); close(fd); return NULL; } pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); if (pk == NULL) { debug("PEM_read_PrivateKey failed"); (void)ERR_get_error(); } else if (pk->type == EVP_PKEY_RSA && (type == KEY_UNSPEC||type==KEY_RSA)) { prv = key_new(KEY_UNSPEC); prv->rsa = EVP_PKEY_get1_RSA(pk); prv->type = KEY_RSA; name = "rsa w/o comment"; #ifdef DEBUG_PK RSA_print_fp(stderr, prv->rsa, 8); #endif if (RSA_blinding_on(prv->rsa, NULL) != 1) { error("key_load_private_pem: RSA_blinding_on failed"); key_free(prv); prv = NULL; } } else if (pk->type == EVP_PKEY_DSA && (type == KEY_UNSPEC||type==KEY_DSA)) { prv = key_new(KEY_UNSPEC); prv->dsa = EVP_PKEY_get1_DSA(pk); prv->type = KEY_DSA; name = "dsa w/o comment"; #ifdef DEBUG_PK DSA_print_fp(stderr, prv->dsa, 8); #endif } else { error("PEM_read_PrivateKey: mismatch or " "unknown EVP_PKEY save_type %d", pk->save_type); } fclose(fp); if (pk != NULL) EVP_PKEY_free(pk); if (prv != NULL && commentp) *commentp = xstrdup(name); debug("read PEM private key done: type %s", prv ? key_type(prv) : "<unknown>"); return prv; }
/* reusable init */ void RSASigner::signerInit( const Context &context, bool isSigning) { StLock<Mutex> _(gMutex()); setIsSigning(isSigning); keyFromContext(context); /* optional padding attribute */ uint32 padding; bool padPresent = context.getInt(CSSM_ATTRIBUTE_PADDING, padding); if(padPresent) { /* padding specified in context, convert to openssl style */ switch(padding) { case CSSM_PADDING_NONE: mPadding = RSA_NO_PADDING; break; case CSSM_PADDING_PKCS1: mPadding = RSA_PKCS1_PADDING; break; default: CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); } } /* optional blinding attribute */ uint32 blinding = context.getInt(CSSM_ATTRIBUTE_RSA_BLINDING); if(blinding) { if(RSA_blinding_on(mRsaKey, NULL) <= 0) { /* actually no legit failures */ CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); } } else { RSA_blinding_off(mRsaKey); } setInitFlag(true); }
static int sshkey_parse_private_pem(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp, char **commentp) { EVP_PKEY *pk = NULL; struct sshkey *prv = NULL; char *name = "<no key>"; BIO *bio = NULL; int r; *keyp = NULL; if (commentp != NULL) *commentp = NULL; if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX) return SSH_ERR_ALLOC_FAIL; if (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) != (int)sshbuf_len(blob)) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase)) == NULL) { r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; } if (pk->type == EVP_PKEY_RSA && (type == KEY_UNSPEC || type == KEY_RSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } prv->rsa = EVP_PKEY_get1_RSA(pk); prv->type = KEY_RSA; name = "rsa w/o comment"; #ifdef DEBUG_PK RSA_print_fp(stderr, prv->rsa, 8); #endif if (RSA_blinding_on(prv->rsa, NULL) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } } else if (pk->type == EVP_PKEY_DSA && (type == KEY_UNSPEC || type == KEY_DSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } prv->dsa = EVP_PKEY_get1_DSA(pk); prv->type = KEY_DSA; name = "dsa w/o comment"; #ifdef DEBUG_PK DSA_print_fp(stderr, prv->dsa, 8); #endif } else if (pk->type == EVP_PKEY_EC && (type == KEY_UNSPEC || type == KEY_ECDSA)) { if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); prv->type = KEY_ECDSA; prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa); if (prv->ecdsa_nid == -1 || sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), EC_KEY_get0_public_key(prv->ecdsa)) != 0 || sshkey_ec_validate_private(prv->ecdsa) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } name = "ecdsa w/o comment"; #ifdef DEBUG_PK if (prv != NULL && prv->ecdsa != NULL) sshkey_dump_ec_key(prv->ecdsa); #endif } else { r = SSH_ERR_INVALID_FORMAT; goto out; } if (commentp != NULL && (*commentp = strdup(name)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } r = 0; *keyp = prv; prv = NULL; out: BIO_free(bio); if (pk != NULL) EVP_PKEY_free(pk); if (prv != NULL) sshkey_free(prv); return r; }
static int sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, struct sshkey **keyp, char **commentp) { int r; u_int16_t check1, check2; u_int8_t cipher_type; struct sshbuf *decrypted = NULL, *copy = NULL; u_char *cp; char *comment = NULL; struct sshcipher_ctx ciphercontext; const struct sshcipher *cipher; struct sshkey *prv = NULL; *keyp = NULL; if (commentp != NULL) *commentp = NULL; /* Check that it is at least big enough to contain the ID string. */ if (sshbuf_len(blob) < sizeof(authfile_id_string)) return SSH_ERR_INVALID_FORMAT; /* * Make sure it begins with the id string. Consume the id string * from the buffer. */ if (memcmp(sshbuf_ptr(blob), authfile_id_string, sizeof(authfile_id_string)) != 0) return SSH_ERR_INVALID_FORMAT; if ((prv = sshkey_new_private(KEY_RSA1)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((copy = sshbuf_fromb(blob)) == NULL || (decrypted = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } if ((r = sshbuf_consume(copy, sizeof(authfile_id_string))) != 0) goto out; /* Read cipher type. */ if ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 || (r = sshbuf_get_u32(copy, NULL)) != 0) /* reserved */ goto out; /* Read the public key and comment from the buffer. */ if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */ (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 || (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 || (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0) goto out; /* Check that it is a supported cipher. */ cipher = cipher_by_number(cipher_type); if (cipher == NULL) { r = SSH_ERR_KEY_UNKNOWN_CIPHER; goto out; } /* Initialize space for decrypted data. */ if ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0) goto out; /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_DECRYPT)) != 0) goto out; if ((r = cipher_crypt(&ciphercontext, cp, sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) { cipher_cleanup(&ciphercontext); goto out; } if ((r = cipher_cleanup(&ciphercontext)) != 0) goto out; if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 || (r = sshbuf_get_u16(decrypted, &check2)) != 0) goto out; if (check1 != check2) { r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; } /* Read the rest of the private key. */ if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 || (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 || (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 || (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0) goto out; /* calculate p-1 and q-1 */ if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0) goto out; /* enable blinding */ if (RSA_blinding_on(prv->rsa, NULL) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } r = 0; *keyp = prv; prv = NULL; if (commentp != NULL) { *commentp = comment; comment = NULL; } out: bzero(&ciphercontext, sizeof(ciphercontext)); if (comment != NULL) free(comment); if (prv != NULL) sshkey_free(prv); if (copy != NULL) sshbuf_free(copy); if (decrypted != NULL) sshbuf_free(decrypted); return r; }
/* * Decode a string to a key. Return 0 on success. */ int kn_decode_key(struct keynote_deckey *dc, char *key, int keytype) { void *kk = NULL; X509 *px509Cert; EVP_PKEY *pPublicKey; unsigned char *ptr = NULL, *decoded = NULL; int encoding, internalencoding; long len = 0; keynote_errno = 0; if (keytype == KEYNOTE_PRIVATE_KEY) dc->dec_algorithm = keynote_get_private_key_algorithm(key, &encoding, &internalencoding); else dc->dec_algorithm = keynote_get_key_algorithm(key, &encoding, &internalencoding); if (dc->dec_algorithm == KEYNOTE_ALGORITHM_NONE) { if ((dc->dec_key = strdup(key)) == NULL) { keynote_errno = ERROR_MEMORY; return -1; } return 0; } key = strchr(key, ':'); /* Move forward, to the Encoding. We're guaranteed * to have a ':' character, since this is a key */ key++; /* Remove ASCII encoding */ switch (encoding) { case ENCODING_NONE: break; case ENCODING_HEX: len = strlen(key) / 2; if (kn_decode_hex(key, (char **) &decoded) != 0) return -1; ptr = decoded; break; case ENCODING_BASE64: len = strlen(key); if (len % 4) /* Base64 encoding must be a multiple of 4 */ { keynote_errno = ERROR_SYNTAX; return -1; } len = 3 * (len / 4); decoded = calloc(len, sizeof(unsigned char)); ptr = decoded; if (decoded == NULL) { keynote_errno = ERROR_MEMORY; return -1; } if ((len = kn_decode_base64(key, decoded, len)) == -1) return -1; break; case ENCODING_NATIVE: decoded = strdup(key); if (decoded == NULL) { keynote_errno = ERROR_MEMORY; return -1; } len = strlen(key); ptr = decoded; break; default: keynote_errno = ERROR_SYNTAX; return -1; } /* DSA-HEX */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_DSA) && (internalencoding == INTERNAL_ENC_ASN1)) { dc->dec_key = DSA_new(); if (dc->dec_key == NULL) { keynote_errno = ERROR_MEMORY; return -1; } kk = dc->dec_key; if (keytype == KEYNOTE_PRIVATE_KEY) { if (d2i_DSAPrivateKey((DSA **) &kk,(const unsigned char **) &decoded, len) == NULL) { free(ptr); DSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } else { if (d2i_DSAPublicKey((DSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { free(ptr); DSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } free(ptr); return 0; } /* RSA-PKCS1-HEX */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_RSA) && (internalencoding == INTERNAL_ENC_PKCS1)) { dc->dec_key = RSA_new(); if (dc->dec_key == NULL) { keynote_errno = ERROR_MEMORY; return -1; } kk = dc->dec_key; if (keytype == KEYNOTE_PRIVATE_KEY) { if (d2i_RSAPrivateKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { free(ptr); RSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } if (RSA_blinding_on((RSA *) kk, NULL) != 1) { free(ptr); RSA_free(kk); keynote_errno = ERROR_MEMORY; return -1; } } else { if (d2i_RSAPublicKey((RSA **) &kk, (const unsigned char **) &decoded, len) == NULL) { free(ptr); RSA_free(kk); keynote_errno = ERROR_SYNTAX; /* Could be a memory error */ return -1; } } free(ptr); return 0; } /* X509 Cert */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_X509) && (internalencoding == INTERNAL_ENC_ASN1) && (keytype == KEYNOTE_PUBLIC_KEY)) { if ((px509Cert = X509_new()) == NULL) { free(ptr); keynote_errno = ERROR_MEMORY; return -1; } if(d2i_X509(&px509Cert, (const unsigned char **)&decoded, len) == NULL) { free(ptr); X509_free(px509Cert); keynote_errno = ERROR_SYNTAX; return -1; } if ((pPublicKey = X509_get_pubkey(px509Cert)) == NULL) { free(ptr); X509_free(px509Cert); keynote_errno = ERROR_SYNTAX; return -1; } /* RSA-specific */ dc->dec_key = pPublicKey->pkey.rsa; free(ptr); return 0; } /* BINARY keys */ if ((dc->dec_algorithm == KEYNOTE_ALGORITHM_BINARY) && (internalencoding == INTERNAL_ENC_NONE)) { dc->dec_key = calloc(1, sizeof(struct keynote_binary)); if (dc->dec_key == NULL) { keynote_errno = ERROR_MEMORY; return -1; } ((struct keynote_binary *) dc->dec_key)->bn_key = decoded; ((struct keynote_binary *) dc->dec_key)->bn_len = len; return RESULT_TRUE; } /* Add support for more algorithms here */ free(ptr); /* This shouldn't ever be reached really */ keynote_errno = ERROR_SYNTAX; return -1; }
int check_validity_of_cert( const char *cFile, const unsigned char *md5_md, unsigned char *sfileMsg, const int sfsize, const char* caPath ) { int retval = 0; X509 *cert; X509_STORE *store; X509_LOOKUP *lookup; X509_STORE_CTX *ctx = 0; EVP_PKEY *pubKey; BIO *bio; bio = BIO_new(BIO_s_file()); BIO_read_filename(bio, cFile); if (NULL == (cert = PEM_read_bio_X509(bio, NULL, 0, NULL))) { BIO_vfree(bio); return 0; } // verify certificate store = X509_STORE_new(); lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); X509_LOOKUP_add_dir(lookup, (char *)caPath, X509_FILETYPE_PEM); if ((ctx = X509_STORE_CTX_new()) != 0) { if (X509_STORE_CTX_init(ctx, store, cert, 0) == 1) retval = X509_verify_cert(ctx); X509_STORE_CTX_free(ctx); } X509_STORE_free(store); if (retval != 1) { fprintf(stderr,"ERROR: Cannot verify certificate ('%s')\n", cFile); return 0; } pubKey = X509_get_pubkey(cert); if (!pubKey) { X509_free(cert); BIO_vfree(bio); return 0; } if (pubKey->type == EVP_PKEY_RSA) { BN_CTX *c = BN_CTX_new(); if (!c) { X509_free(cert); EVP_PKEY_free(pubKey); BIO_vfree(bio); return 0; } if (!RSA_blinding_on(pubKey->pkey.rsa, c)) { X509_free(cert); EVP_PKEY_free(pubKey); BIO_vfree(bio); BN_CTX_free(c); return 0; } retval = RSA_verify(NID_md5, md5_md, MD5_DIGEST_LENGTH, sfileMsg, sfsize, pubKey->pkey.rsa); RSA_blinding_off(pubKey->pkey.rsa); BN_CTX_free(c); } if (pubKey->type == EVP_PKEY_DSA) { fprintf(stderr, "ERROR: DSA keys are not supported.\n"); return 0; } EVP_PKEY_free(pubKey); X509_free(cert); BIO_vfree(bio); return retval; }
/* called by CSPFullPluginSession */ void RSA_CryptContext::init(const Context &context, bool encoding /*= true*/) { StLock<Mutex> _(gMutex()); if(mInitFlag && !opStarted()) { /* reusing - e.g. query followed by encrypt */ return; } /* optional mode to use alternate key class (e.g., decrypt with public key) */ CSSM_KEYCLASS keyClass; switch (context.getInt(CSSM_ATTRIBUTE_MODE)) { case CSSM_ALGMODE_PUBLIC_KEY: keyClass = CSSM_KEYCLASS_PUBLIC_KEY; break; case CSSM_ALGMODE_PRIVATE_KEY: keyClass = CSSM_KEYCLASS_PRIVATE_KEY; break; case CSSM_ALGMODE_NONE: /* default, not present in context: infer from op type */ keyClass = encoding ? CSSM_KEYCLASS_PUBLIC_KEY : CSSM_KEYCLASS_PRIVATE_KEY; break; default: CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE); } /* fetch key from context */ if(mRsaKey == NULL) { assert(!opStarted()); CSSM_DATA label = {0, NULL}; mRsaKey = contextToRsaKey(context, session(), keyClass, encoding ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT, mAllocdRsaKey, label); if(label.Data) { mLabel.copy(label); mOaep = true; free(label.Data); } } else { assert(opStarted()); } unsigned cipherBlockSize = RSA_size(mRsaKey); unsigned plainBlockSize; /* padding - not present means value zero, CSSM_PADDING_NONE */ uint32 padding = context.getInt(CSSM_ATTRIBUTE_PADDING); switch(padding) { case CSSM_PADDING_NONE: mPadding = RSA_NO_PADDING; plainBlockSize = cipherBlockSize; break; case CSSM_PADDING_PKCS1: mPadding = RSA_PKCS1_PADDING; plainBlockSize = cipherBlockSize - 11; break; case CSSM_PADDING_APPLE_SSLv2: rsaCryptDebug("RSA_CryptContext::init using CSSM_PADDING_APPLE_SSLv2"); mPadding = RSA_SSLV23_PADDING; plainBlockSize = cipherBlockSize - 11; break; default: rsaCryptDebug("RSA_CryptContext::init bad padding (0x%x)", (unsigned)padding); CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); } /* optional blinding attribute */ uint32 blinding = context.getInt(CSSM_ATTRIBUTE_RSA_BLINDING); if(blinding) { if(RSA_blinding_on(mRsaKey, NULL) <= 0) { /* actually no legit failures */ CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); } } else { RSA_blinding_off(mRsaKey); } /* finally, have BlockCryptor set up its stuff. */ setup(encoding ? plainBlockSize : cipherBlockSize, // blockSizeIn encoding ? cipherBlockSize : plainBlockSize, // blockSizeOut false, // pkcs5Pad false, // needsFinal BCM_ECB, NULL); // IV mInitFlag = true; }
// Signing functions bool OSSLRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { if (mechanism == AsymMech::RSA_PKCS) { // Separate implementation for RSA PKCS #1 signing without hash computation // Check if the private key is the right type if (!privateKey->isOfType(OSSLRSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // In case of PKCS #1 signing the length of the input data may not exceed 40% of the // modulus size OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey; size_t allowedLen = osslKey->getN().size() - 11; if (dataToSign.size() > allowedLen) { ERROR_MSG("Data to sign exceeds maximum for PKCS #1 signature"); return false; } // Perform the signature operation signature.resize(osslKey->getN().size()); RSA* rsa = osslKey->getOSSLKey(); if (!RSA_blinding_on(rsa, NULL)) { ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key"); return false; } int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_PKCS1_PADDING); RSA_blinding_off(rsa); if (sigLen == -1) { ERROR_MSG("An error occurred while performing a PKCS #1 signature"); return false; } signature.resize(sigLen); return true; } else if (mechanism == AsymMech::RSA) { // Separate implementation for raw RSA signing // Check if the private key is the right type if (!privateKey->isOfType(OSSLRSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // In case of raw RSA, the length of the input data must match the length of the modulus OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey; if (dataToSign.size() != osslKey->getN().size()) { ERROR_MSG("Size of data to sign does not match the modulus size"); return false; } // Perform the signature operation signature.resize(osslKey->getN().size()); RSA* rsa = osslKey->getOSSLKey(); if (!RSA_blinding_on(rsa, NULL)) { ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key"); return false; } int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_NO_PADDING); RSA_blinding_off(rsa); if (sigLen == -1) { ERROR_MSG("An error occurred while performing a raw RSA signature"); return false; } signature.resize(sigLen); return true; } else { // Call default implementation return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen); } }
static Key * key_load_private_rsa1(int fd, const char *filename, const char *passphrase, char **commentp) { int i, check1, check2, cipher_type; off_t len; Buffer buffer, decrypted; u_char *cp; CipherContext ciphercontext; Cipher *cipher; Key *prv = NULL; struct stat st; if (fstat(fd, &st) < 0) { error("fstat for key file %.200s failed: %.100s", filename, strerror(errno)); close(fd); return NULL; } len = st.st_size; buffer_init(&buffer); cp = buffer_append_space(&buffer, len); if (read(fd, cp, (size_t) len) != (size_t) len) { debug("Read from key file %.200s failed: %.100s", filename, strerror(errno)); buffer_free(&buffer); close(fd); return NULL; } /* Check that it is at least big enough to contain the ID string. */ if (len < sizeof(authfile_id_string)) { debug3("Not a RSA1 key file %.200s.", filename); buffer_free(&buffer); close(fd); return NULL; } /* * Make sure it begins with the id string. Consume the id string * from the buffer. */ for (i = 0; i < sizeof(authfile_id_string); i++) if (buffer_get_char(&buffer) != authfile_id_string[i]) { debug3("Not a RSA1 key file %.200s.", filename); buffer_free(&buffer); close(fd); return NULL; } /* Read cipher type. */ cipher_type = buffer_get_char(&buffer); (void) buffer_get_int(&buffer); /* Reserved data. */ /* Read the public key from the buffer. */ (void) buffer_get_int(&buffer); prv = key_new_private(KEY_RSA1); buffer_get_bignum(&buffer, prv->rsa->n); buffer_get_bignum(&buffer, prv->rsa->e); if (commentp) *commentp = buffer_get_string(&buffer, NULL); else xfree(buffer_get_string(&buffer, NULL)); /* Check that it is a supported cipher. */ cipher = cipher_by_number(cipher_type); if (cipher == NULL) { debug("Unsupported cipher %d used in key file %.200s.", cipher_type, filename); buffer_free(&buffer); goto fail; } /* Initialize space for decrypted data. */ buffer_init(&decrypted); cp = buffer_append_space(&decrypted, buffer_len(&buffer)); /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_DECRYPT); cipher_crypt(&ciphercontext, cp, buffer_ptr(&buffer), buffer_len(&buffer)); cipher_cleanup(&ciphercontext); memset(&ciphercontext, 0, sizeof(ciphercontext)); buffer_free(&buffer); check1 = buffer_get_char(&decrypted); check2 = buffer_get_char(&decrypted); if (check1 != buffer_get_char(&decrypted) || check2 != buffer_get_char(&decrypted)) { if (strcmp(passphrase, "") != 0) debug("Bad passphrase supplied for key file %.200s.", filename); /* Bad passphrase. */ buffer_free(&decrypted); goto fail; } /* Read the rest of the private key. */ buffer_get_bignum(&decrypted, prv->rsa->d); buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */ /* in SSL and SSH v1 p and q are exchanged */ buffer_get_bignum(&decrypted, prv->rsa->q); /* p */ buffer_get_bignum(&decrypted, prv->rsa->p); /* q */ /* calculate p-1 and q-1 */ rsa_generate_additional_parameters(prv->rsa); buffer_free(&decrypted); /* enable blinding */ if (RSA_blinding_on(prv->rsa, NULL) != 1) { error("key_load_private_rsa1: RSA_blinding_on failed"); goto fail; } close(fd); return prv; fail: if (commentp) xfree(*commentp); close(fd); key_free(prv); return NULL; }
EVP_PKEY *pki_evp::decryptKey() const { unsigned char *p; const unsigned char *p1; int outl, decsize; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char ckey[EVP_MAX_KEY_LENGTH]; EVP_PKEY *tmpkey; EVP_CIPHER_CTX ctx; const EVP_CIPHER *cipher = EVP_des_ede3_cbc(); char ownPassBuf[MAX_PASS_LENGTH] = ""; if (isPubKey()) { unsigned char *q; outl = i2d_PUBKEY(key, NULL); p = q = (unsigned char *)OPENSSL_malloc(outl); check_oom(q); i2d_PUBKEY(key, &p); p = q; tmpkey = d2i_PUBKEY(NULL, (const unsigned char**)&p, outl); OPENSSL_free(q); return tmpkey; } /* This key has its own password */ if (ownPass == ptPrivate) { int ret; pass_info pi(XCA_TITLE, qApp->translate("MainWindow", "Please enter the password to decrypt the private key: '%1'").arg(getIntName())); ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &pi); if (ret < 0) throw errorEx(tr("Password input aborted"), class_name); } else if (ownPass == ptBogus) { // BOGUS pass ownPassBuf[0] = '\0'; } else { memcpy(ownPassBuf, passwd, MAX_PASS_LENGTH); //printf("Orig password: '******' len:%d\n", passwd, strlen(passwd)); while (md5passwd(ownPassBuf) != passHash && sha512passwd(ownPassBuf, passHash) != passHash) { int ret; //printf("Passhash= '%s', new hash= '%s', passwd= '%s'\n", //CCHAR(passHash), CCHAR(md5passwd(ownPassBuf)), ownPassBuf); pass_info p(XCA_TITLE, tr("Please enter the database password for decrypting the key '%1'").arg(getIntName())); ret = MainWindow::passRead(ownPassBuf, MAX_PASS_LENGTH, 0, &p); if (ret < 0) throw errorEx(tr("Password input aborted"), class_name); } } //printf("Using decrypt Pass: %s\n", ownPassBuf); p = (unsigned char *)OPENSSL_malloc(encKey.count()); check_oom(p); pki_openssl_error(); p1 = p; memset(iv, 0, EVP_MAX_IV_LENGTH); memcpy(iv, encKey.constData(), 8); /* recover the iv */ /* generate the key */ EVP_BytesToKey(cipher, EVP_sha1(), iv, (unsigned char *)ownPassBuf, strlen(ownPassBuf), 1, ckey,NULL); /* we use sha1 as message digest, * because an md5 version of the password is * stored in the database... */ EVP_CIPHER_CTX_init(&ctx); EVP_DecryptInit(&ctx, cipher, ckey, iv); EVP_DecryptUpdate(&ctx, p , &outl, (const unsigned char*)encKey.constData() +8, encKey.count() -8); decsize = outl; EVP_DecryptFinal(&ctx, p + decsize , &outl); decsize += outl; //printf("Decrypt decsize=%d, encKey_len=%d\n", decsize, encKey_len); pki_openssl_error(); tmpkey = d2i_PrivateKey(key->type, NULL, &p1, decsize); pki_openssl_error(); OPENSSL_free(p); EVP_CIPHER_CTX_cleanup(&ctx); pki_openssl_error(); if (EVP_PKEY_type(tmpkey->type) == EVP_PKEY_RSA) RSA_blinding_on(tmpkey->pkey.rsa, NULL); return tmpkey; }
static int RSA_eay_private_decrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM f,ret; int j,num=0,r= -1; unsigned char *p; unsigned char *buf=NULL; BN_CTX *ctx=NULL; BN_init(&f); BN_init(&ret); ctx=BN_CTX_new(); if (ctx == NULL) goto err; num=BN_num_bytes(rsa->n); if ((buf=(unsigned char *)Malloc(num)) == NULL) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); goto err; } /* This check was for equality but PGP does evil things * and chops off the top '0' bytes */ if (flen > num) { RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } /* make data into a big number */ if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err; if ((rsa->flags & RSA_FLAG_BLINDING) && (RSA_get_thread_blinding_ptr(rsa) == NULL)) RSA_blinding_on(rsa,ctx); if (rsa->flags & RSA_FLAG_BLINDING) if (!BN_BLINDING_convert(&f,RSA_get_thread_blinding_ptr(rsa),ctx)) goto err; /* do the decrypt */ if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL)) ) { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; } else { if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err; } if (rsa->flags & RSA_FLAG_BLINDING) if (!BN_BLINDING_invert(&ret,RSA_get_thread_blinding_ptr(rsa),ctx)) goto err; p=buf; j=BN_bn2bin(&ret,p); /* j is only used with no-padding mode */ switch (padding) { case RSA_PKCS1_PADDING: r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num); break; #ifndef _OPENSSL_APPLE_CDSA_ #ifndef NO_SHA case RSA_PKCS1_OAEP_PADDING: r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0); break; #endif #endif case RSA_SSLV23_PADDING: r=RSA_padding_check_SSLv23(to,num,buf,j,num); break; case RSA_NO_PADDING: r=RSA_padding_check_none(to,num,buf,j,num); break; default: RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) BN_CTX_free(ctx); BN_clear_free(&f); BN_clear_free(&ret); if (buf != NULL) { memset(buf,0,num); Free(buf); } return(r); }
static int RSA_eay_private_encrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM f,ret; int i,j,k,num=0,r= -1; unsigned char *buf=NULL; BN_CTX *ctx=NULL; BN_init(&f); BN_init(&ret); if ((ctx=BN_CTX_new()) == NULL) goto err; num=BN_num_bytes(rsa->n); if ((buf=(unsigned char *)Malloc(num)) == NULL) { RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen); break; case RSA_NO_PADDING: i=RSA_padding_add_none(buf,num,from,flen); break; case RSA_SSLV23_PADDING: default: RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) goto err; if (BN_bin2bn(buf,num,&f) == NULL) goto err; if ((rsa->flags & RSA_FLAG_BLINDING) && (RSA_get_thread_blinding_ptr(rsa) == NULL)) RSA_blinding_on(rsa,ctx); if (rsa->flags & RSA_FLAG_BLINDING) if (!BN_BLINDING_convert(&f,RSA_get_thread_blinding_ptr(rsa),ctx)) goto err; if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL)) ) { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; } else { if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err; } if (rsa->flags & RSA_FLAG_BLINDING) if (!BN_BLINDING_invert(&ret,RSA_get_thread_blinding_ptr(rsa),ctx)) goto err; /* put in leading 0 bytes if the number is less than the * length of the modulus */ j=BN_num_bytes(&ret); i=BN_bn2bin(&ret,&(to[num-j])); for (k=0; k<(num-i); k++) to[k]=0; r=num; err: if (ctx != NULL) BN_CTX_free(ctx); BN_clear_free(&ret); BN_clear_free(&f); if (buf != NULL) { memset(buf,0,num); Free(buf); } return(r); }
/* Encrypt the HASH into a SIG type. */ static int rsa_sig_encode_hash (struct message *msg) { struct exchange *exchange = msg->exchange; struct ipsec_exch *ie = exchange->data; size_t hashsize = ie->hash->hashsize; struct cert_handler *handler; char header[80]; int initiator = exchange->initiator; u_int8_t *buf, *data, *buf2; u_int32_t datalen; u_int8_t *id; size_t id_len; int idtype; void *sent_key; id = initiator ? exchange->id_i : exchange->id_r; id_len = initiator ? exchange->id_i_len : exchange->id_r_len; /* We may have been provided these by the kernel */ buf = (u_int8_t *)conf_get_str (exchange->name, "Credentials"); if (buf && (idtype = conf_get_num (exchange->name, "Credential_Type", -1) != -1)) { exchange->sent_certtype = idtype; handler = cert_get (idtype); if (!handler) { log_print ("rsa_sig_encode_hash: cert_get (%d) failed", idtype); return -1; } exchange->sent_cert = handler->cert_from_printable ((char *)buf); if (!exchange->sent_cert) { log_print ("rsa_sig_encode_hash: failed to retrieve certificate"); return -1; } handler->cert_serialize (exchange->sent_cert, &data, &datalen); if (!data) { log_print ("rsa_sig_encode_hash: cert serialization failed"); return -1; } goto aftercert; /* Skip all the certificate discovery */ } /* XXX This needs to be configurable. */ idtype = ISAKMP_CERTENC_KEYNOTE; /* Find a certificate with subjectAltName = id. */ handler = cert_get (idtype); if (!handler) { idtype = ISAKMP_CERTENC_X509_SIG; handler = cert_get (idtype); if (!handler) { log_print ("rsa_sig_encode_hash: cert_get(%d) failed", idtype); return -1; } } if (handler->cert_obtain (id, id_len, 0, &data, &datalen) == 0) { if (idtype == ISAKMP_CERTENC_KEYNOTE) { idtype = ISAKMP_CERTENC_X509_SIG; handler = cert_get (idtype); if (!handler) { log_print ("rsa_sig_encode_hash: cert_get(%d) failed", idtype); return -1; } if (handler->cert_obtain (id, id_len, 0, &data, &datalen) == 0) { LOG_DBG ((LOG_MISC, 10, "rsa_sig_encode_hash: no certificate to send")); goto skipcert; } } else { LOG_DBG ((LOG_MISC, 10, "rsa_sig_encode_hash: no certificate to send")); goto skipcert; } } /* Let's store the certificate we are going to use */ exchange->sent_certtype = idtype; exchange->sent_cert = handler->cert_get (data, datalen); if (!exchange->sent_cert) { free (data); log_print ("rsa_sig_encode_hash: failed to get certificate from wire " "encoding"); return -1; } aftercert: buf = realloc (data, ISAKMP_CERT_SZ + datalen); if (!buf) { log_error ("rsa_sig_encode_hash: realloc (%p, %d) failed", data, ISAKMP_CERT_SZ + datalen); free (data); return -1; } memmove (buf + ISAKMP_CERT_SZ, buf, datalen); SET_ISAKMP_CERT_ENCODING (buf, idtype); if (message_add_payload (msg, ISAKMP_PAYLOAD_CERT, buf, ISAKMP_CERT_SZ + datalen, 1)) { free (buf); return -1; } skipcert: /* Again, we may have these from the kernel */ buf = (u_int8_t *)conf_get_str (exchange->name, "PKAuthentication"); if (buf) { key_from_printable (ISAKMP_KEY_RSA, ISAKMP_KEYTYPE_PRIVATE, (char *)buf, &data, &datalen); if (!data || datalen == -1) { log_print ("rsa_sig_encode_hash: badly formatted RSA private key"); return 0; } sent_key = key_internalize (ISAKMP_KEY_RSA, ISAKMP_KEYTYPE_PRIVATE, data, datalen); if (!sent_key) { log_print ("rsa_sig_encode_hash: bad RSA private key from dynamic " "SA acquisition subsystem"); return 0; } #if defined (USE_PRIVSEP) { /* With USE_PRIVSEP, the sent_key should be a key number. */ void *key = sent_key; sent_key = monitor_RSA_upload_key (key); } #endif } else /* Try through the regular means. */ { switch (id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ]) { case IPSEC_ID_IPV4_ADDR: case IPSEC_ID_IPV6_ADDR: util_ntoa ((char **)&buf2, id[ISAKMP_ID_TYPE_OFF - ISAKMP_GEN_SZ] == IPSEC_ID_IPV4_ADDR ? AF_INET : AF_INET6, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ); if (!buf2) return 0; break; case IPSEC_ID_FQDN: case IPSEC_ID_USER_FQDN: buf2 = calloc (id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1, sizeof (char)); if (!buf2) { log_print ("rsa_sig_encode_hash: malloc (%lu) failed", (unsigned long)id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1); return 0; } memcpy (buf2, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ, id_len - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ); break; /* XXX Support more ID types? */ default: buf2 = 0; return 0; } #if defined (USE_PRIVSEP) sent_key = monitor_RSA_get_private_key (exchange->name, (char *)buf2); #else sent_key = ike_auth_get_key (IKE_AUTH_RSA_SIG, exchange->name, (char *)buf2, 0); #endif free (buf2); /* Did we find a key? */ if (!sent_key) { log_print ("rsa_sig_encode_hash: could not get private key"); return -1; } } #if !defined (USE_PRIVSEP) /* Enable RSA blinding. */ if (RSA_blinding_on (sent_key, NULL) != 1) { log_error ("rsa_sig_encode_hash: RSA_blinding_on () failed."); return -1; } #endif /* XXX hashsize is not necessarily prf->blocksize. */ buf = malloc (hashsize); if (!buf) { log_error ("rsa_sig_encode_hash: malloc (%lu) failed", (unsigned long)hashsize); return -1; } if (ike_auth_hash (exchange, buf) == -1) { free (buf); return -1; } snprintf (header, sizeof header, "rsa_sig_encode_hash: HASH_%c", initiator ? 'I' : 'R'); LOG_DBG_BUF ((LOG_MISC, 80, header, buf, hashsize)); #if !defined (USE_PRIVSEP) data = malloc (RSA_size (sent_key)); if (!data) { log_error ("rsa_sig_encode_hash: malloc (%d) failed", RSA_size (sent_key)); return -1; } datalen = RSA_private_encrypt (hashsize, buf, data, sent_key, RSA_PKCS1_PADDING); #else datalen = monitor_RSA_private_encrypt (hashsize, buf, &data, sent_key, RSA_PKCS1_PADDING); #endif /* USE_PRIVSEP */ if (datalen == -1) { log_print ("rsa_sig_encode_hash: RSA_private_encrypt () failed"); if (data) free (data); free (buf); monitor_RSA_free (sent_key); return -1; } free (buf); buf = realloc (data, ISAKMP_SIG_SZ + datalen); if (!buf) { log_error ("rsa_sig_encode_hash: realloc (%p, %d) failed", data, ISAKMP_SIG_SZ + datalen); free (data); return -1; } memmove (buf + ISAKMP_SIG_SZ, buf, datalen); snprintf (header, sizeof header, "rsa_sig_encode_hash: SIG_%c", initiator ? 'I' : 'R'); LOG_DBG_BUF ((LOG_MISC, 80, header, buf + ISAKMP_SIG_DATA_OFF, datalen)); if (message_add_payload (msg, ISAKMP_PAYLOAD_SIG, buf, ISAKMP_SIG_SZ + datalen, 1)) { free (buf); return -1; } return 0; }
Key *key_private_deserialize(buffer_t *blob) { int success = 0; char *type_name = NULL; Key *k = NULL; unsigned int pklen, sklen; int type; type_name = buffer_get_string_msg(blob, NULL); if (type_name == NULL) goto error; type = get_keytype_from_name(type_name); k = key_new_private(type); switch (type) { case KEY_RSA: buffer_get_bignum2_msg(blob, k->rsa->n); buffer_get_bignum2_msg(blob, k->rsa->e); buffer_get_bignum2_msg(blob, k->rsa->d); buffer_get_bignum2_msg(blob, k->rsa->iqmp); buffer_get_bignum2_msg(blob, k->rsa->p); buffer_get_bignum2_msg(blob, k->rsa->q); /* Generate additional parameters */ rsa_generate_additional_parameters(k->rsa); break; case KEY_DSA: buffer_get_bignum2_msg(blob, k->dsa->p); buffer_get_bignum2_msg(blob, k->dsa->q); buffer_get_bignum2_msg(blob, k->dsa->g); buffer_get_bignum2_msg(blob, k->dsa->pub_key); buffer_get_bignum2_msg(blob, k->dsa->priv_key); break; case KEY_ECDSA256: case KEY_ECDSA384: case KEY_ECDSA521: { int success = 0; unsigned int nid; char *curve = NULL; ssh_keytype skt; BIGNUM *exponent = NULL; EC_POINT *q = NULL; nid = keytype_to_cipher_nid(type); curve = buffer_get_string_msg(blob, NULL); skt = key_curve_name_to_keytype(curve); if (nid != keytype_to_cipher_nid(skt)) goto ecdsa_error; k->ecdsa = EC_KEY_new_by_curve_name(nid); if (k->ecdsa == NULL) goto ecdsa_error; q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa)); if (q == NULL) goto ecdsa_error; if ((exponent = BN_new()) == NULL) goto ecdsa_error; buffer_get_ecpoint_msg(blob, EC_KEY_get0_group(k->ecdsa), q); buffer_get_bignum2_msg(blob, exponent); if (EC_KEY_set_public_key(k->ecdsa, q) != 1) goto ecdsa_error; if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) goto ecdsa_error; if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), EC_KEY_get0_public_key(k->ecdsa)) != 0) goto ecdsa_error; if (key_ec_validate_private(k->ecdsa) != 0) goto ecdsa_error; success = 1; ecdsa_error: free(curve); if (exponent) BN_clear_free(exponent); if (q) EC_POINT_free(q); if (success == 0) goto error; } break; case KEY_ED25519: k->ed25519_pk = buffer_get_string_msg(blob, &pklen); k->ed25519_sk = buffer_get_string_msg(blob, &sklen); if (pklen != ED25519_PK_SZ) goto error; if (sklen != ED25519_SK_SZ) goto error; break; default: goto error; break; } /* enable blinding */ switch (k->type) { case KEY_RSA1: case KEY_RSA: if (RSA_blinding_on(k->rsa, NULL) != 1) goto error; break; } success = 1; error: free(type_name); if (success == 0) { key_free(k); k = NULL; } return (k); }
bool OSSLRSA::signFinal(ByteString& signature) { // Save necessary state before calling super class signFinal OSSLRSAPrivateKey* pk = (OSSLRSAPrivateKey*) currentPrivateKey; AsymMech::Type mechanism = currentMechanism; if (!AsymmetricAlgorithm::signFinal(signature)) { return false; } ByteString firstHash, secondHash; bool bFirstResult = pCurrentHash->hashFinal(firstHash); bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true; delete pCurrentHash; pCurrentHash = NULL; if (pSecondHash != NULL) { delete pSecondHash; pSecondHash = NULL; } if (!bFirstResult || !bSecondResult) { return false; } ByteString digest = firstHash + secondHash; // Resize the data block for the signature to the modulus size of the key signature.resize(pk->getN().size()); // Determine the signature NID type int type = 0; bool isPSS = false; const EVP_MD* hash = NULL; switch (mechanism) { case AsymMech::RSA_MD5_PKCS: type = NID_md5; break; case AsymMech::RSA_SHA1_PKCS: type = NID_sha1; break; case AsymMech::RSA_SHA224_PKCS: type = NID_sha224; break; case AsymMech::RSA_SHA256_PKCS: type = NID_sha256; break; case AsymMech::RSA_SHA384_PKCS: type = NID_sha384; break; case AsymMech::RSA_SHA512_PKCS: type = NID_sha512; break; case AsymMech::RSA_SHA1_PKCS_PSS: isPSS = true; hash = EVP_sha1(); break; case AsymMech::RSA_SHA224_PKCS_PSS: isPSS = true; hash = EVP_sha224(); break; case AsymMech::RSA_SHA256_PKCS_PSS: isPSS = true; hash = EVP_sha256(); break; case AsymMech::RSA_SHA384_PKCS_PSS: isPSS = true; hash = EVP_sha384(); break; case AsymMech::RSA_SHA512_PKCS_PSS: isPSS = true; hash = EVP_sha512(); break; case AsymMech::RSA_SSL: type = NID_md5_sha1; break; default: break; } // Perform the signature operation unsigned int sigLen = signature.size(); RSA* rsa = pk->getOSSLKey(); if (!RSA_blinding_on(rsa, NULL)) { ERROR_MSG("Failed to turn blinding on for OpenSSL RSA key"); return false; } bool rv; if (isPSS) { ByteString em; em.resize(pk->getN().size()); rv = (RSA_padding_add_PKCS1_PSS(pk->getOSSLKey(), &em[0], &digest[0], hash, sLen) == 1); if (!rv) { ERROR_MSG("RSA PSS padding failed (0x%08X)", ERR_get_error()); } else { int result = RSA_private_encrypt(em.size(), &em[0], &signature[0], pk->getOSSLKey(), RSA_NO_PADDING); if (result >= 0) { sigLen = result; rv = true; } else { rv = false; ERROR_MSG("RSA private encrypt failed (0x%08X)", ERR_get_error()); } } } else { rv = (RSA_sign(type, &digest[0], digest.size(), &signature[0], &sigLen, pk->getOSSLKey()) == 1); } RSA_blinding_off(rsa); signature.resize(sigLen); return rv; }
inline void rsa_key::enable_blinding(BN_CTX* ctx) const { error::throw_error_if_not(RSA_blinding_on(ptr().get(), ctx) != 0); }