| 509 | } |
| 510 | |
| 511 | void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, |
| 512 | std::shared_ptr<const BlindedPublicKey> key, std::shared_ptr<LocalDestination> dest, const uint8_t * secret) |
| 513 | { |
| 514 | size_t offset = 0; |
| 515 | // blinded key |
| 516 | if (len < 2) return; |
| 517 | const uint8_t * stA1 = buf + offset; // stA1 = blinded signature type, 2 bytes big endian |
| 518 | uint16_t blindedKeyType = bufbe16toh (stA1); offset += 2; |
| 519 | std::unique_ptr<i2p::crypto::Verifier> blindedVerifier (i2p::data::IdentityEx::CreateVerifier (blindedKeyType)); |
| 520 | if (!blindedVerifier) return; |
| 521 | auto blindedKeyLen = blindedVerifier->GetPublicKeyLen (); |
| 522 | if (offset + blindedKeyLen >= len) return; |
| 523 | const uint8_t * blindedPublicKey = buf + offset; |
| 524 | blindedVerifier->SetPublicKey (blindedPublicKey); offset += blindedKeyLen; |
| 525 | // expiration |
| 526 | if (offset + 8 >= len) return; |
| 527 | const uint8_t * publishedTimestamp = buf + offset; |
| 528 | m_PublishedTimestamp = bufbe32toh (publishedTimestamp); offset += 4; // published timestamp (seconds) |
| 529 | uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds) |
| 530 | SetExpirationTime ((m_PublishedTimestamp + expires)*1000LL); // in milliseconds |
| 531 | uint16_t flags = bufbe16toh (buf + offset); offset += 2; // flags |
| 532 | if (flags & LEASESET2_FLAG_OFFLINE_KEYS) |
| 533 | { |
| 534 | // transient key |
| 535 | m_TransientVerifier = ProcessOfflineSignature (blindedVerifier, buf, len, offset); |
| 536 | if (!m_TransientVerifier) |
| 537 | { |
| 538 | LogPrint (eLogError, "LeaseSet2: Offline signature failed"); |
| 539 | return; |
| 540 | } |
| 541 | } |
| 542 | // outer ciphertext |
| 543 | if (offset + 2 > len) return; |
| 544 | uint16_t lenOuterCiphertext = bufbe16toh (buf + offset); offset += 2; |
| 545 | const uint8_t * outerCiphertext = buf + offset; |
| 546 | offset += lenOuterCiphertext; |
| 547 | // verify signature |
| 548 | bool verified = m_TransientVerifier ? VerifySignature (m_TransientVerifier, buf, len, offset) : |
| 549 | VerifySignature (blindedVerifier, buf, len, offset); |
| 550 | SetIsValid (verified); |
| 551 | // handle ciphertext |
| 552 | if (verified && key && lenOuterCiphertext >= 32) |
| 553 | { |
| 554 | SetIsValid (false); // we must verify it again in Layer 2 |
| 555 | if (blindedKeyType == key->GetBlindedSigType ()) |
| 556 | { |
| 557 | // verify blinding |
| 558 | char date[9]; |
| 559 | i2p::util::GetDateString (m_PublishedTimestamp, date); |
| 560 | std::vector<uint8_t> blinded (blindedKeyLen); |
| 561 | key->GetBlindedKey (date, blinded.data ()); |
| 562 | if (memcmp (blindedPublicKey, blinded.data (), blindedKeyLen)) |
| 563 | { |
| 564 | LogPrint (eLogError, "LeaseSet2: Blinded public key doesn't match"); |
| 565 | return; |
| 566 | } |
| 567 | } |
| 568 | else |
nothing calls this directly
no test coverage detected