char const* Authenticator::computeDigestResponse(char const* cmd, char const* url) const { // The "response" field is computed as: // md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<url>)) // or, if "fPasswordIsMD5" is True: // md5(<password>:<nonce>:md5(<cmd>:<url>)) char ha1Buf[33]; if (fPasswordIsMD5) { strncpy(ha1Buf, password(), 32); ha1Buf[32] = '\0'; // just in case } else { unsigned const ha1DataLen = strlen(username()) + 1 + strlen(realm()) + 1 + strlen(password()); unsigned char* ha1Data = new unsigned char[ha1DataLen+1]; sprintf((char*)ha1Data, "%s:%s:%s", username(), realm(), password()); our_MD5Data(ha1Data, ha1DataLen, ha1Buf); delete[] ha1Data; } unsigned const ha2DataLen = strlen(cmd) + 1 + strlen(url); unsigned char* ha2Data = new unsigned char[ha2DataLen+1]; sprintf((char*)ha2Data, "%s:%s", cmd, url); char ha2Buf[33]; our_MD5Data(ha2Data, ha2DataLen, ha2Buf); delete[] ha2Data; unsigned const digestDataLen = 32 + 1 + strlen(nonce()) + 1 + 32; unsigned char* digestData = new unsigned char[digestDataLen+1]; sprintf((char*)digestData, "%s:%s:%s", ha1Buf, nonce(), ha2Buf); char const* result = our_MD5Data(digestData, digestDataLen, NULL); delete[] digestData; return result; }
std::string Authenticator::getAuthHeader(std::string method, std::string uri) { std::string result = "Authorization: "; if (fAuthMethod == AUTH_BASIC) { result += "Basic " + base64Encode( username() + ":" + password() ); } else if (fAuthMethod == AUTH_DIGEST) { result += std::string("Digest ") + "username=\"" + quote(username()) + "\", realm=\"" + quote(realm()) + "\", " + "nonce=\"" + quote(nonce()) + "\", uri=\"" + quote(uri) + "\""; if ( ! fQop.empty() ) { result += ", qop=" + fQop; result += ", nc=" + stringtf("%08x",nc); result += ", cnonce=\"" + fCnonce + "\""; } result += ", response=\"" + computeDigestResponse(method, uri) + "\""; result += ", algorithm=\"MD5\""; //Authorization: Digest username="******", // realm="NC-336PW-HD-1080P", // nonce="de8859d97609a6fcc16eaba490dcfd80", // uri="rtsp://10.192.16.8:554/live/0/h264.sdp", // response="4092120557d3099a163bd51a0d59744d", // algorithm=MD5, // opaque="5ccc069c403ebaf9f0171e9517f40e41", // qop="auth", // cnonce="c8051140765877dc", // nc=00000001 } result += "\r\n"; return result; }
extern void nonce_proxy(unsigned char * N) { nonce(N); symL("nonce", "nonce", SIZE_NONCE, FALSE); store_buf(N); }
int main () { int x =2; int y =3; printf("%f\n", div(1, 2.0)); /* This is 0.5 because of the 2.0 being a floating number not an * integer since it has the '.o' at the end. This changes it to * a floating point division */ printf("%d\n", div(twice(nonce(y)), nonce(twice(x)))); /* If you expand this out it would look like: * div(twice(x-x),nonce(x+x) then * twice(y-y)/twice(x) - twice(x) */ return 0; }
String CryptoUtil::Nonce(const uint32_t size, OTData& rawOutput) const { rawOutput.zeroMemory(); rawOutput.SetSize(size); OTPassword source; source.randomizeMemory(size); String nonce(Base58CheckEncode(source)); rawOutput.Assign(source.getMemory(), source.getMemorySize()); return nonce; }
void Connection::_incoming(const std::string& packet) { // data packet: '\0',rid,pktid, [data type, data](A'<>B') std::string nonce(packet.substr(1,8+8)); std::string packet_id(packet.substr(1+8,8)); assert(_nonces); if ( ! _nonces->open(packet_id) ) return; // out of order / replay / ours nonce.resize(crypto_box_NONCEBYTES,'\0'); std::string m; if ( ! _naclsession.decrypt( packet.substr(1+8+8) , nonce , m ) ) return; _ch(_their_id, m[0], m.substr(1)); }
bool dtls_dispatch::check_port_detect_nonce(const uint8_t* nonce_data, const sockaddrunion& fromaddr) { port_detect_nonce nonce(nonce_data); auto it = port_nonce_map.find(nonce); if(it != port_nonce_map.end()) { dout() << "Got port detect nonce " << std::hex << nonce.nonce0 << " " << nonce.nonce1 << std::dec << " from " << fromaddr; if(auto ptr = it->second.lock()) { ip_info from(fromaddr); snow_port_detect reply(from.addr.ip6.s6_addr, from.port); ptr->get_conn().send(reinterpret_cast<uint8_t*>(&reply), sizeof(reply)); } port_nonce_map.erase(it); return true; } else { dout() << "16-byte UDP packet from " << fromaddr << " was not a recognized port detect nonce"; } return false; }
verifyne::Ticket *verifyne::Api::request_new_ticket(std::string purpose, verifyne::Ticket::TICKET_TYPE ticket_type) { /* Generate fresh nonce */ std::random_device rd; std::uniform_int_distribution<int> distribution(0,255); std::stringstream ss_nonce; for(int i = 0; i < 16; i++) { ss_nonce << std::hex << distribution(rd); } std::string nonce(ss_nonce.str()); verifyne::ApiResponse *ar = new_ticket(purpose, nonce, ticket_type); verifyne::Ticket *ticket = new verifyne::Ticket(ar); delete ar; return ticket; }
QByteArray Toxme::prepareEncryptedJson(QString url, int action, QString payload) { QPair<QByteArray, QByteArray> keypair = Core::getInstance()->getKeypair(); if (keypair.first.isEmpty() || keypair.second.isEmpty()) { qWarning() << "prepareEncryptedJson: Couldn't get our keypair, aborting"; return QByteArray(); } QNetworkReply::NetworkError error = QNetworkReply::NoError; QByteArray key = getServerPubkey(url, error); if (error != QNetworkReply::NoError) return QByteArray(); QByteArray nonce(crypto_box_NONCEBYTES, 0); randombytes((uint8_t*)nonce.data(), crypto_box_NONCEBYTES); QByteArray payloadData = payload.toUtf8(); const size_t cypherlen = crypto_box_MACBYTES + payloadData.size(); unsigned char* payloadEnc = new unsigned char[cypherlen]; int cryptResult = crypto_box_easy(payloadEnc, (uint8_t*)payloadData.data(), payloadData.size(), (uint8_t*)nonce.data(), (unsigned char*)key.constData(), (uint8_t*)keypair.second.data()); if (cryptResult != 0) // error return QByteArray(); QByteArray payloadEncData(reinterpret_cast<char*>(payloadEnc), cypherlen); delete[] payloadEnc; const QString json{"{\"action\":" + QString().setNum(action) + "," "\"public_key\":\"" + keypair.first.toHex() + "\"," "\"encrypted\":\"" + payloadEncData.toBase64() + "\"," "\"nonce\":\"" + nonce.toBase64() + "\"}"}; return json.toUtf8(); }
int create_map_register_header(char *buf, int *offset, struct record *request_dest){ /* count dest records */ int dest_record_count = 0; struct record *ptr = request_dest; while(ptr->next != NULL){ dest_record_count++; ptr = ptr->next; } struct register_header *header = (struct register_header *)buf; header->type = 3; header->proxy_bit = 1; header->notify_bit = 0; header->record_count = dest_record_count; nonce((char *)header->nonce, 8); header->key_id = htons(1); header->auth_len = htons(SHA_DIGEST_LENGTH); *offset += sizeof(struct register_header); return 0; }
std::string Authenticator::computeDigestResponse(std::string &method, std::string &uri) { #if HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT // The "response" field is computed as: // md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<url>)) size_t md5len = 16; unsigned char md5buf[md5len]; char md5HexBuf[md5len*2+1]; // Step 1: md5(<username>:<realm>:<password>) std::string ha1Data = username() + ":" + realm() + ":" + password(); Debug( 2, "HA1 pre-md5: %s", ha1Data.c_str() ); #if HAVE_DECL_MD5 MD5((unsigned char*)ha1Data.c_str(), ha1Data.length(), md5buf); #elif HAVE_DECL_GNUTLS_FINGERPRINT gnutls_datum_t md5dataha1 = { (unsigned char*)ha1Data.c_str(), ha1Data.length() }; gnutls_fingerprint( GNUTLS_DIG_MD5, &md5dataha1, md5buf, &md5len ); #endif for ( unsigned int j = 0; j < md5len; j++ ) { sprintf(&md5HexBuf[2*j], "%02x", md5buf[j] ); } md5HexBuf[md5len*2]='\0'; std::string ha1Hash = md5HexBuf; // Step 2: md5(<cmd>:<url>) std::string ha2Data = method + ":" + uri; Debug( 2, "HA2 pre-md5: %s", ha2Data.c_str() ); #if HAVE_DECL_MD5 MD5((unsigned char*)ha2Data.c_str(), ha2Data.length(), md5buf ); #elif HAVE_DECL_GNUTLS_FINGERPRINT gnutls_datum_t md5dataha2 = { (unsigned char*)ha2Data.c_str(), ha2Data.length() }; gnutls_fingerprint( GNUTLS_DIG_MD5, &md5dataha2, md5buf, &md5len ); #endif for ( unsigned int j = 0; j < md5len; j++ ) { sprintf( &md5HexBuf[2*j], "%02x", md5buf[j] ); } md5HexBuf[md5len*2]='\0'; std::string ha2Hash = md5HexBuf; // Step 3: md5(ha1:<nonce>:ha2) std::string digestData = ha1Hash + ":" + nonce(); if ( ! fQop.empty() ) { digestData += ":" + stringtf("%08x", nc) + ":"+fCnonce + ":" + fQop; nc ++; // if qop was specified, then we have to include t and a cnonce and an nccount } digestData += ":" + ha2Hash; Debug( 2, "pre-md5: %s", digestData.c_str() ); #if HAVE_DECL_MD5 MD5((unsigned char*)digestData.c_str(), digestData.length(), md5buf); #elif HAVE_DECL_GNUTLS_FINGERPRINT gnutls_datum_t md5datadigest = { (unsigned char*)digestData.c_str(), digestData.length() }; gnutls_fingerprint( GNUTLS_DIG_MD5, &md5datadigest, md5buf, &md5len ); #endif for ( unsigned int j = 0; j < md5len; j++ ) { sprintf( &md5HexBuf[2*j], "%02x", md5buf[j] ); } md5HexBuf[md5len*2]='\0'; return md5HexBuf; #else // HAVE_DECL_MD5 Error( "You need to build with gnutls or openssl installed to use digest authentication" ); return( 0 ); #endif // HAVE_DECL_MD5 }
void CStateAuthentication::ProcessDataL(const TDesC8& aData) { //free resources delete iRequestData; iRequestData = NULL; if(aData.Size()!=0) { if(iResponseData == NULL) { iResponseData = aData.AllocL(); } else { TInt size = iResponseData->Size(); iResponseData = iResponseData->ReAllocL(size+aData.Size()); //TODO:check this iResponseData->Des().Append(aData); } return; } // parse response from server if(iResponseData->Find(KApplicationOS)==KErrNotFound) { //server answered with a redirect iObserver.ResponseError(KErrAuth); return; } //retrieve cookie HBufC8* cookie = CRestUtils::GetCookieL(*iResponseData); TBuf8<32> cookieBuf(*cookie); delete cookie; iObserver.SetCookie(cookieBuf); //extract body from response RBuf8 body(CRestUtils::GetBodyL(*iResponseData)); body.CleanupClosePushL(); // first 32 bytes are Crypt(Signature,Ks) TPtrC8 crypt2 = body.Left(32); // retrieve Ks RBuf8 Ks(AES::DecryptPkcs5L(crypt2,KIV,iSignKey)); Ks.CleanupClosePushL(); // then calculate K=sha1(confKey,Ks,Kd), take only first 16 bytes of sha1 CSHA1* sha1 = CSHA1::NewL(); CleanupStack::PushL(sha1); sha1->Update(iConfKey); sha1->Update(Ks); TBuf8<20> keyK; keyK.Copy(sha1->Final(iKd)); CleanupStack::PopAndDestroy(sha1); keyK.SetLength(16); CleanupStack::PopAndDestroy(&Ks); //set K key iObserver.SetKey(keyK); // last bytes are Crypt(K,Nonce | Response) TPtrC8 crypt3 = body.Right(body.Size()-32); RBuf8 plain(AES::DecryptPkcs5L(crypt3,KIV,keyK)); plain.CleanupClosePushL(); TBufC8<16> nonce(plain.Left(16)); TBufC8<4> response(plain.Right(4)); CleanupStack::PopAndDestroy(&plain); CleanupStack::PopAndDestroy(&body); //verify nonce if(iNonce.Compare(nonce)!=0) { iObserver.ResponseError(KErrAuth); return; } //verify response if(response.Compare(KProto_Ok)==0) { // it's ok, let's go on iObserver.ChangeStateL(); return; } if(response.Compare(KProto_No)==0) { iObserver.ResponseError(KErrAuth); return; } if(response.Compare(KProto_CmdUninstall)==0) { CAbstractState* uninstall = CStateCmdUninstall::NewL(iObserver); uninstall->ActivateL(KNullDesC8); return; } }
int wmain (int argc, wchar_t **argv) { win32_exception::setCodePage(CP_OEMCP); try { WS32 _______; std::wstring domain(L"TMG"), hostname(L"PC0048"); TcpClientSocket socket("10.12.0.60", 8080); ntlm_request_t request(narrow(domain), narrow(hostname)); std::stringstream temp; temp << request; std::string temps = temp.str(); std::string http_request_start = "GET http://www.yandex.ru/ HTTP/1.1\r\n" "Host: www.yandex.ru\r\n" //"Connection: close\r\n" ; std::string proxy_auth = "Proxy-Authorization: NTLM "; std::string http_request; http_request = http_request_start + proxy_auth + base64_encode(std::begin(temps), std::end(temps)) + "\r\n\r\n"; std::cout << http_request << "======END OF REQUEST======" << std::endl; socket.send(std::begin(http_request), std::end(http_request)); // std::vector<BYTE> response(8 * 1024, 0); // auto last = std::end(response); // for (auto it = std::begin(response), eit = std::end(response); it != last; last = it, it = socket.recv_upto(it, eit)); HttpResponse response(socket); print_response(response, socket); auto headers = response.getHeaders(); auto proxyauth = headers.find("Proxy-Authenticate"); if (std::end(headers) == proxyauth) { std::cout << "Expected a Proxy-Authenticate header in response" << std::endl; return 1; } if (proxyauth->second.size() > 1) { std::cout << "Multiple Proxy-Authenticate headers are not allowed" << std::endl; return 2; } if (proxyauth->second.begin()->substr(0, 5) != "NTLM ") { std::cout << "Expected NTLM token in Proxy-Authenticate header" << std::endl; return 3; } std::string tmp = proxyauth->second.begin()->substr(5); std::vector<BYTE> challenge = base64_decode(std::begin(tmp), std::end(tmp)); size_t challen = challenge.size(); if (challen <= 48) { std::cout << "NTLM challenge message is too short" << std::endl; return 4; } unsigned short tbofs, tpos, ttype = 0, tblen = 0; tbofs = tpos = challenge[44] | (challenge[45] << 8); while (tpos + 4 <= challen && (ttype = challenge[tpos] | (challenge[tpos + 1] << 8))) { unsigned short tlen = challenge[tpos + 2] | (challenge[tpos + 3] << 8); if (tpos + 4 + tlen > challen) break; tpos += 4 + tlen; tblen += 4 + tlen; } if (tblen && ttype == 0) tblen += 4; CryptoProvider provider; std::string username, password; std::cout << "Enter the username: "******"Enter the password: "******"NTLMSSP\0", 8); *(DWORD*)&ntlm_resp[8] = 3; *(WORD*)&ntlm_resp[12] = lmhash.size(); *(WORD*)&ntlm_resp[14] = lmhash.size(); *(DWORD*)&ntlm_resp[16] = 64 + dlen + ulen + hlen; *(WORD*)&ntlm_resp[20] = nthash.size(); *(WORD*)&ntlm_resp[22] = nthash.size(); *(DWORD*)&ntlm_resp[24] = 64 + dlen + ulen + hlen + lmhash.size(); *(WORD*)&ntlm_resp[28] = dlen; *(WORD*)&ntlm_resp[30] = dlen; *(DWORD*)&ntlm_resp[32] = 64; *(WORD*)&ntlm_resp[36] = ulen; *(WORD*)&ntlm_resp[38] = ulen; *(DWORD*)&ntlm_resp[40] = 64 + dlen; *(WORD*)&ntlm_resp[44] = hlen; *(WORD*)&ntlm_resp[46] = hlen; *(WORD*)&ntlm_resp[48] = 64 + dlen + ulen; /* Session */ *(WORD*)&ntlm_resp[52] = 0; *(WORD*)&ntlm_resp[54] = 0; *(DWORD*)&ntlm_resp[56] = 64 + dlen + ulen + hlen + lmhash.size() + nthash.size(); /* Flags */ *(DWORD*)&ntlm_resp[60] = *(DWORD*)&challenge[20]; memcpy(&ntlm_resp[64], domain.data(), dlen); memcpy(&ntlm_resp[64 + dlen], wusername.data(), ulen); memcpy(&ntlm_resp[64 + dlen + ulen], hostname.data(), hlen); memcpy(&ntlm_resp[64 + dlen + ulen + hlen], lmhash.data(), lmhash.size()); memcpy(&ntlm_resp[64 + dlen + ulen + hlen + lmhash.size()], nthash.data(), nthash.size()); std::string z = base64_encode(ntlm_resp.begin(), ntlm_resp.end()); http_request = http_request_start + proxy_auth + z + "\r\n\r\n"; std::cout << http_request << "======END OF REQUEST======" << std::endl; socket.send(http_request.begin(), http_request.end()); HttpResponse second_resp(socket); print_response(second_resp, socket); { http_request = "GET http://mail.ru/ HTTP/1.1\r\nHost: mail.ru\r\n\r\n"; socket.send(http_request.begin(), http_request.end()); HttpResponse r(socket); print_response(r, socket); } } catch (std::exception& e) { std::cout << e.what() << std::endl; } return 0; }
int main(int argc, char ** argv) { unsigned char * pkey, * skey, * xkey; size_t pkey_len, skey_len, xkey_len; unsigned char * m1, * m1_all; unsigned char * Na; size_t m1_len, m1_e_len, m1_all_len; unsigned char * m2, * m2_e; unsigned char * xNb; size_t m2_len, m2_e_len; size_t m2_l1, m2_l2; unsigned char * m3_e; size_t m3_e_len; unsigned char * p; // for encryption tags unsigned char * etag = malloc(4); BIO * bio = socket_connect(); pkey = get_pkey(&pkey_len, 'A'); skey = get_skey(&skey_len, 'A'); xkey = get_xkey(&xkey_len, 'A'); #ifdef VERBOSE printf("pkey = "); print_buffer(pkey, pkey_len); printf("\n"); printf("skey = "); print_buffer(skey, skey_len); printf("\n"); printf("xkey = "); print_buffer(xkey, xkey_len); printf("\n"); #endif /* Send message 1 */ m1_len = SIZE_NONCE + 4 + pkey_len + sizeof(size_t); p = m1 = malloc(m1_len); memcpy(p, "msg1", 4); p += 4; * (size_t *) p = SIZE_NONCE; p += sizeof(size_t); Na = p; nonce(Na); p += SIZE_NONCE; memcpy(p, pkey, pkey_len); m1_e_len = encrypt_len(xkey, xkey_len, m1, m1_len); m1_all_len = m1_e_len + sizeof(size_t) + 4; m1_all = malloc(m1_all_len); memcpy(m1_all, "encr", 4); m1_e_len = encrypt(xkey, xkey_len, m1, m1_len, m1_all + sizeof(m1_e_len) + 4); m1_all_len = m1_e_len + sizeof(size_t) + 4; * (size_t *) (m1_all + 4) = m1_e_len; send(bio, m1_all, m1_all_len); #ifdef VERBOSE printf("A: m1_e sent, m1_e = "); print_buffer(m1_all, m1_all_len); printf("\n"); fflush(stdout); #endif /* Receive message 2 */ recv(bio, etag, 4); recv(bio, (unsigned char*) &m2_e_len, sizeof(m2_e_len)); m2_e = malloc(m2_e_len); recv(bio, m2_e, m2_e_len); m2_len = decrypt_len(skey, skey_len, m2_e, m2_e_len); m2 = malloc(m2_len); m2_len = decrypt(skey, skey_len, m2_e, m2_e_len, m2); if(xkey_len + 2 * SIZE_NONCE + 2 * sizeof(size_t) + 4 != m2_len) { printf("A: m2 has wrong length\n"); exit(1); } if(memcmp(m2, "msg2", 4)) { printf("A: m2 not properly tagged\n"); exit(1); } m2_l1 = *(size_t *) (m2 + 4); m2_l2 = *(size_t *) (m2 + 4 + sizeof(size_t)); if(m2_l1 != SIZE_NONCE) { printf("A: m2 has wrong length for xNa\n"); exit(1); } if(m2_l2 != SIZE_NONCE) { printf("A: m2 has wrong length for xNb\n"); exit(1); } if(memcmp(m2 + 4 + 2 * sizeof(size_t), Na, m2_l1)) { printf("A: xNa in m2 doesn't match Na\n"); exit(1); } #ifndef LOWE_ATTACK if(memcmp(m2 + m2_l1 + m2_l2 + 2 * sizeof(size_t) + 4, xkey, xkey_len)) { printf("A: x_xkey in m2 doesn't match xkey\n"); exit(1); } #endif xNb = m2 + m2_l1 + 2 * sizeof(size_t) + 4; #ifdef VERBOSE printf("A: m2 received and checked"); printf("\n"); fflush(stdout); #endif /* Send message 3 */ m3_e_len = encrypt_len(xkey, xkey_len, xNb, m2_l2); m3_e = malloc(m3_e_len + sizeof(size_t) + 4); memcpy(m3_e, "encr", 4); m3_e_len = encrypt(xkey, xkey_len, xNb, m2_l2, m3_e + sizeof(m3_e_len) + 4); * (size_t *)(m3_e + 4) = m3_e_len; send(bio, m3_e, m3_e_len + sizeof(m3_e_len) + 4); #ifdef VERBOSE printf("A: m3 sent"); printf("\n"); fflush(stdout); #endif #ifdef VERBOSE printf("A: Na = "); print_buffer(Na, SIZE_NONCE); printf("\n"); printf("A: Nb = "); print_buffer(xNb, SIZE_NONCE); printf("\n"); fflush(stdout); #endif return 0; }
int main(int argc, char ** argv) { // our identity and the identity of the other partner unsigned char * host, * xhost; size_t host_len, xhost_len; unsigned char * pkey, * skey, * xkey; size_t pkey_len, skey_len, xkey_len; unsigned char * m1, * m1_e; unsigned char * xNa, * xNb; size_t m1_len, m1_e_len; size_t m1_l; unsigned char * m2, * m2_e; unsigned char * Nb; size_t m2_len, m2_e_len; unsigned char * m3, * m3_e; size_t m3_len, m3_e_len; unsigned char * p; // for dropping encryption tags unsigned char * dummy = malloc(4); BIO * bio = socket_listen(); host = get_host(&host_len, 'B'); pkey = get_pkey(&pkey_len, 'B'); skey = get_skey(&skey_len, 'B'); #ifdef VERBOSE printf("B pkey = "); print_buffer(pkey, pkey_len); printf("\n"); printf("B skey = "); print_buffer(skey, skey_len); printf("\n"); #endif /* Receive message 1 */ recv(bio, (unsigned char*) &m1_e_len, sizeof(m1_e_len)); if(m1_e_len > MAX_SIZE_CIPHER) fail("Server: cipher in message 1 too long"); m1_e = malloc(m1_e_len); recv(bio, m1_e, m1_e_len); m1_len = decrypt_len(skey, skey_len, m1_e, m1_e_len); m1 = malloc(m1_len); m1_len = decrypt(skey, skey_len, m1_e, m1_e_len, m1); if(sizeof(size_t) + SIZE_NONCE + 4 > m1_len) { fprintf(stderr, "m1 has wrong length\n"); exit(1); } if(memcmp(m1, "msg1", 4)) { fprintf(stderr, "B: m1 not properly tagged, aborting\n"); exit(1); } m1_l = * (size_t *) (m1 + 4); if(m1_l != SIZE_NONCE) { fprintf(stderr, "A: m1 contains wrong length for xNa\n"); exit(1); } xhost_len = m1_len - (4 + sizeof(size_t) + m1_l); xhost = m1 + 4 + sizeof(size_t) + m1_l; if(xhost_len > MAX_SIZE_HOST) fail("B: host size in m1 too long"); #ifdef VERBOSE printf("B xhost = "); print_buffer(xhost, xhost_len); printf("\n"); #endif xkey = lookup_xkey(&xkey_len, xhost, xhost_len, 'B'); #ifdef VERBOSE printf("B xkey = "); print_buffer(xkey, xkey_len); printf("\n"); #endif /* if(memcmp(m1 + sizeof(size_t) + m1_l + 4, xkey, xkey_len)) { fprintf(stderr, "x_xkey in m1 doesn't match xkey\n"); exit(1); } */ xNa = m1 + 4 + sizeof(size_t); typehint(xNa, m1_l, "fixed_20_nonce"); #ifdef VERBOSE fprintf(stderr, "B: m1 received and checked"); fprintf(stderr, "\n"); fflush(stderr); #endif #ifdef CSEC_VERIFY #ifdef USE_EVENT_PARAMS event2("server_begin", xhost, xhost_len, host, host_len); #else event0("server_begin"); #endif #endif /* Send message 2 */ m2_len = 2 * SIZE_NONCE + 2 * sizeof(size_t) + 4 + host_len; p = m2 = malloc(m2_len); memcpy(p, "msg2", 4); p += 4; * (size_t *) p = m1_l; p += sizeof(size_t); * (size_t *) p = SIZE_NONCE; p += sizeof(size_t); memcpy(p, xNa, m1_l); p += m1_l; Nb = p; nonce(Nb); p += SIZE_NONCE; memcpy(p, host, host_len); m2_e_len = encrypt_len(xkey, xkey_len, m2, m2_len); if(m2_e_len > MAX_SIZE_CIPHER) fail("Server: cipher in message 2 too long"); m2_e = malloc(m2_e_len); m2_e_len = encrypt(xkey, xkey_len, m2, m2_len, m2_e); send(bio, &m2_e_len, sizeof(m2_e_len)); send(bio, m2_e, m2_e_len); #ifdef VERBOSE printf("B: m2_e sent, m2_e = "); print_buffer(m2_e, m2_e_len); printf("\n"); fflush(stdout); #endif /* Receive message 3 */ recv(bio, (unsigned char*) &m3_e_len, sizeof(m3_e_len)); if(m3_e_len > MAX_SIZE_CIPHER) fail("Server: cipher in message 3 too long"); m3_e = malloc(m3_e_len); recv(bio, m3_e, m3_e_len); m3_len = decrypt_len(skey, skey_len, m3_e, m3_e_len); m3 = malloc(m3_len); m3_len = decrypt(skey, skey_len, m3_e, m3_e_len, m3); if(memcmp(m3, "msg3", 4)) { fprintf(stderr, "B: m3 not properly tagged, aborting\n"); exit(1); } if(m3_len != SIZE_NONCE + 4) { fprintf(stderr, "B: m3 has wrong length\n"); exit(1); } xNb = m3 + 4; typehint(xNb, SIZE_NONCE, "fixed_20_nonce"); if(memcmp(xNb, Nb, SIZE_NONCE)) { fprintf(stderr, "xNb in m3 doesn't match Nb\n"); exit(1); } #ifdef VERBOSE printf("B: Na = "); print_buffer(xNa, SIZE_NONCE); printf("\n"); printf("B: Nb = "); print_buffer(Nb, SIZE_NONCE); printf("\n"); fflush(stdout); #endif #ifdef CSEC_VERIFY #ifdef USE_EVENT_PARAMS event2("server_end", xhost, xhost_len, host, host_len); #else event0("server_end"); #endif #endif // wait for the client to close, to avoid "Address already in use" errors wait_close(bio); return 0; }