void SendChallenge(void* remoteKey, Session& route, const std::shared_ptr<GlobalGrid::VSocket>& socket) { void* challenge = RSA_Encrypt(remoteKey,(unsigned char*)route.challenge,16); unsigned char* challenge_bytes; size_t challenge_size; GlobalGrid::Buffer_Get(challenge,&challenge_bytes,&challenge_size); size_t aligned_challenge = 1+2+challenge_size; aligned_challenge+=16-(aligned_challenge % 16); unsigned char* xmitPacket = new unsigned char[aligned_challenge]; memset(xmitPacket,0,aligned_challenge); uint16_t pc_sz = (uint16_t)challenge_size; //TODO: Transmit size of RSA encrypted blob along with actual blob memcpy(xmitPacket+1,&pc_sz,2); memcpy(xmitPacket+1+2,challenge_bytes,challenge_size); for(size_t i = 0;i<aligned_challenge;i+=16) { aes_encrypt(route.key,xmitPacket+i); } socket->Send(xmitPacket,aligned_challenge); delete[] xmitPacket; GlobalGrid::GGObject_Free(challenge); }
void Handshake(const std::shared_ptr<GlobalGrid::VSocket>& socket, void* remoteKey) { //Remote thumbprint + AES session key unsigned char thumbprint[16]; Session session(socket); session.verified = true; //If they can send back a response (properly encoded; that is); we know that we're verified. secure_random_bytes(session.key,32); RSA_thumbprint(remoteKey,thumbprint); //Encrypt second part of message containing AES session key void* buffy = RSA_Encrypt(remoteKey,session.key,32); unsigned char* buffy_bytes; size_t buffy_size; GlobalGrid::Buffer_Get(buffy,&buffy_bytes,&buffy_size); //Be careful. Buffy bytes! unsigned char* mander = new unsigned char[16+buffy_size]; memcpy(mander,thumbprint,16); memcpy(mander+16,buffy_bytes,buffy_size); socket->Send(mander,16+buffy_size); //Send Charmander into battle. sessions.insert(session); delete[] mander; GlobalGrid::GGObject_Free(buffy); }
/* * Encrypt/Decrypt */ OSStatus sslRsaEncrypt( SSLContext *ctx, SSLPubKey *pubKey, const uint32_t padding, const uint8_t *plainText, size_t plainTextLen, uint8_t *cipherText, // mallocd by caller; RETURNED size_t cipherTextLen, // available size_t *actualBytes) // RETURNED { #if 0 gi_uint16 giCipherTextLen = cipherTextLen; RSAStatus rsaStatus; assert(actualBytes != NULL); rsaStatus = RSA_Encrypt(&pubKey->rsaKey, RP_PKCS1, getRandomByte, plainText, plainTextLen, cipherText, &giCipherTextLen); *actualBytes = giCipherTextLen; return rsaStatus ? rsaStatusToSSL(rsaStatus) : noErr; #else size_t ctlen = cipherTextLen; assert(actualBytes != NULL); #if RSA_PUB_KEY_USAGE_HACK /* Force key usage to allow encryption with public key */ #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) const CSSM_KEY_PTR cssmKey = NULL; if (SecKeyGetCSSMKey(SECKEYREF(pubKey), &cssmKey)==noErr && cssmKey) cssmKey->KeyHeader.KeyUsage |= CSSM_KEYUSE_ENCRYPT; #endif #endif OSStatus status = SecKeyEncrypt(SECKEYREF(pubKey), padding, plainText, plainTextLen, cipherText, &ctlen); if (status) { sslErrorLog("sslRsaEncrypt: SecKeyEncrypt failed (error %d)\n", status); } /* Since the KeyExchange already allocated modulus size bytes we'll use all of them. SecureTransport has always sent that many bytes, so we're not going to deviate, to avoid interoperability issues. */ if (!status && (ctlen < cipherTextLen)) { size_t offset = cipherTextLen - ctlen; memmove(cipherText + offset, cipherText, ctlen); memset(cipherText, 0, offset); ctlen = cipherTextLen; } if (actualBytes) *actualBytes = ctlen; if (status) sslErrorLog("***sslRsaEncrypt: error %d\n", status); return status; #endif }