| 643 | } |
| 644 | |
| 645 | size_t LeaseSet2::ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const |
| 646 | { |
| 647 | size_t offset = 0; |
| 648 | uint8_t flag = buf[offset]; offset++; // flag |
| 649 | if (flag & 0x01) // client auth |
| 650 | { |
| 651 | if (!(flag & 0x0E)) // DH, bit 1-3 all zeroes |
| 652 | { |
| 653 | const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey |
| 654 | uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients |
| 655 | const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients |
| 656 | if (offset > len) |
| 657 | { |
| 658 | LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data"); |
| 659 | return 0; |
| 660 | } |
| 661 | // calculate authCookie |
| 662 | if (secret) |
| 663 | { |
| 664 | i2p::crypto::X25519Keys ck (secret, nullptr); // derive cpk_i from csk_i |
| 665 | uint8_t authInput[100]; |
| 666 | ck.Agree (ephemeralPublicKey, authInput); // sharedSecret is first 32 bytes of authInput |
| 667 | memcpy (authInput + 32, ck.GetPublicKey (), 32); // cpk_i |
| 668 | memcpy (authInput + 64, subcredential, 36); |
| 669 | uint8_t okm[64]; // 52 actual data |
| 670 | i2p::crypto::HKDF (ephemeralPublicKey, authInput, 100, "ELS2_XCA", okm); |
| 671 | if (!GetAuthCookie (authClients, numClients, okm, authCookie)) |
| 672 | LogPrint (eLogError, "LeaseSet2: Client cookie DH not found"); |
| 673 | } |
| 674 | else |
| 675 | LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: csk_i is not provided"); |
| 676 | } |
| 677 | else if (flag & 0x02) // PSK, bit 1 is set to 1 |
| 678 | { |
| 679 | const uint8_t * authSalt = buf + offset; offset += 32; // authSalt |
| 680 | uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients |
| 681 | const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients |
| 682 | if (offset > len) |
| 683 | { |
| 684 | LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data"); |
| 685 | return 0; |
| 686 | } |
| 687 | // calculate authCookie |
| 688 | if (secret) |
| 689 | { |
| 690 | uint8_t authInput[68]; |
| 691 | memcpy (authInput, secret, 32); |
| 692 | memcpy (authInput + 32, subcredential, 36); |
| 693 | uint8_t okm[64]; // 52 actual data |
| 694 | i2p::crypto::HKDF (authSalt, authInput, 68, "ELS2PSKA", okm); |
| 695 | if (!GetAuthCookie (authClients, numClients, okm, authCookie)) |
| 696 | LogPrint (eLogError, "LeaseSet2: Client cookie PSK not found"); |
| 697 | } |
| 698 | else |
| 699 | LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: psk_i is not provided"); |
| 700 | } |
| 701 | else |
| 702 | LogPrint (eLogError, "LeaseSet2: Unknown client auth type ", (int)flag); |
nothing calls this directly
no test coverage detected