void crypto_rsa_encrypt(int len, uint8 * in, uint8 * out, uint32 modulus_size, uint8 * modulus, uint8 * exponent) { SECKEYPublicKey pubKey; pubKey.arena = NULL; pubKey.keyType = rsaKey; pubKey.pkcs11Slot = NULL; pubKey.pkcs11ID = CK_INVALID_HANDLE; pubKey.u.rsa.arena = NULL; pubKey.u.rsa.modulus.type = siUnsignedInteger; pubKey.u.rsa.modulus.data = modulus; pubKey.u.rsa.modulus.len = modulus_size; pubKey.u.rsa.publicExponent.type = siUnsignedInteger; pubKey.u.rsa.publicExponent.data = exponent; pubKey.u.rsa.publicExponent.len = SEC_EXPONENT_SIZE; ASSERT(modulus_size <= SEC_MAX_MODULUS_SIZE); uint8 in_be[SEC_MAX_MODULUS_SIZE]; memset(in_be, 0, modulus_size - len); /* must be padded to modulus_size */ memcpy(in_be + modulus_size - len, in, len); SECStatus s = PK11_PubEncryptRaw(&pubKey, out, in_be, modulus_size, NULL); check(s, "Error rsa-encrypting"); ASSERT(pubKey.pkcs11Slot); PK11_FreeSlot(pubKey.pkcs11Slot); }
inPubKey.m_exponent.data = (unsigned char *) PORT_Alloc(explen + 10); memcpy(inPubKey.m_exponent.data, temp, explen); inPubKey.m_exponent.len = explen; inPubKey.m_exponent.type = siUnsignedInteger; g_free(temp); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); SEC_ASN1EncodeItem(arena, &derPubKey, &inPubKey, MyRSAPublicKeyTemplate); pubKey = SECKEY_ImportDERPublicKey(&derPubKey, CKK_RSA); PORT_FreeArena(arena, PR_FALSE); encrypted = g_new0(guchar, modlen); temp = pkcs1pad2(password, modlen); /* encrypt password, result will be in encrypted */ rv = PK11_PubEncryptRaw(pubKey, encrypted, temp, modlen, 0); g_free(temp); if (rv != SECSuccess) { purple_debug_error("steam", "password encrypt failed\n"); if (pubKey) SECKEY_DestroyPublicKey(pubKey); g_free(encrypted); return NULL; } /*tmpstr = BTOA_DataToAscii(encrypted, modlen); output = g_strdup(tmpstr); PORT_Free(tmpstr);*/ output = purple_base64_encode(encrypted, modlen);
unsigned int NSSCryptoKeyRSA::publicEncrypt(const unsigned char * inBuf, unsigned char * cipherBuf, unsigned int inLength, unsigned int maxOutLength, PaddingType padding, hashMethod hm) { // Perform an encrypt if (mp_pubkey == 0) { throw XSECCryptoException(XSECCryptoException::RSAError, "NSS:RSA - Attempt to encrypt data with empty key"); } unsigned int encryptSize = SECKEY_PublicKeyStrength(mp_pubkey); if (maxOutLength < encryptSize) { throw XSECCryptoException(XSECCryptoException::RSAError, "NSS:RSA - Too small buffer for encrypted buffer output"); } SECStatus s; unsigned char * buf; XSECnew(buf, unsigned char[encryptSize]); ArrayJanitor<unsigned char> j_buf(buf); switch (padding) { case XSECCryptoKeyRSA::PAD_PKCS_1_5 : // do the padding (http://www.w3.org/TR/xmlenc-core/#rsa-1_5) { // generate random data for padding SECStatus s = PK11_GenerateRandom(buf, encryptSize); if (s != SECSuccess) { throw XSECException(XSECException::InternalError, "NSSCryptoKeyRSA() - Error generating Random data"); } // first byte have to be 0x02 buf[0] = 0x00; buf[1] = 0x02; // check that there are no 0x00 bytes among random data for (unsigned int i = 2; i < encryptSize - inLength - 1; i++) { while (buf[i] == 0x00) { // replace all 0x00 occurences in random data with random value PK11_GenerateRandom(&buf[i], 1); } } // before key add 0x00 byte buf[encryptSize - inLength - 1] = 0x00; // at the end of input buffer (to be encrypted) add key memcpy(&buf[encryptSize - inLength], inBuf, inLength); } // encrypt s = PK11_PubEncryptRaw(mp_pubkey, cipherBuf, (unsigned char*)buf, encryptSize, NULL); if (s != SECSuccess) { throw XSECCryptoException(XSECCryptoException::RSAError, "NSS:RSA publicKeyEncrypt - Error performing encrypt"); } break; case XSECCryptoKeyRSA::PAD_OAEP_MGFP1 : throw XSECCryptoException(XSECCryptoException::RSAError, "NSS:RSA - OAEP padding method not supported in NSS yet"); break; default : throw XSECCryptoException(XSECCryptoException::RSAError, "NSS:RSA - Unknown padding method"); } return encryptSize; }