(
wrapped_packet: &[u8],
dnscrypt_encryption_params_set: &[Arc<DNSCryptEncryptionParams>],
pq_ticket_key: &pq::TicketKey,
pq_enabled: bool,
)
| 59 | } |
| 60 | |
| 61 | pub fn decrypt( |
| 62 | wrapped_packet: &[u8], |
| 63 | dnscrypt_encryption_params_set: &[Arc<DNSCryptEncryptionParams>], |
| 64 | pq_ticket_key: &pq::TicketKey, |
| 65 | pq_enabled: bool, |
| 66 | ) -> Result<(EncryptionParams, Vec<u8>), Error> { |
| 67 | ensure!(wrapped_packet.len() >= DNSCRYPT_QUERY_MAGIC_SIZE, "Short packet"); |
| 68 | |
| 69 | if pq_enabled && wrapped_packet[..pq::PQ_RESUME_MAGIC.len()] == pq::PQ_RESUME_MAGIC { |
| 70 | return decrypt_pq_resumed(wrapped_packet, dnscrypt_encryption_params_set, pq_ticket_key); |
| 71 | } |
| 72 | |
| 73 | let client_magic = &wrapped_packet[..DNSCRYPT_QUERY_MAGIC_SIZE]; |
| 74 | |
| 75 | if pq_enabled { |
| 76 | if let Some(params) = dnscrypt_encryption_params_set |
| 77 | .iter() |
| 78 | .find(|p| p.pq().is_some_and(|pq| pq.client_magic() == client_magic)) |
| 79 | { |
| 80 | return decrypt_pq_ciphertext(wrapped_packet, params, pq_ticket_key); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | ensure!( |
| 85 | wrapped_packet.len() |
| 86 | >= DNSCRYPT_QUERY_MAGIC_SIZE |
| 87 | + DNSCRYPT_QUERY_PK_SIZE |
| 88 | + DNSCRYPT_QUERY_NONCE_SIZE |
| 89 | + DNS_HEADER_SIZE, |
| 90 | "Short packet" |
| 91 | ); |
| 92 | let client_pk = &wrapped_packet |
| 93 | [DNSCRYPT_QUERY_MAGIC_SIZE..DNSCRYPT_QUERY_MAGIC_SIZE + DNSCRYPT_QUERY_PK_SIZE]; |
| 94 | let client_nonce = &wrapped_packet[DNSCRYPT_QUERY_MAGIC_SIZE + DNSCRYPT_QUERY_PK_SIZE |
| 95 | ..DNSCRYPT_QUERY_MAGIC_SIZE + DNSCRYPT_QUERY_PK_SIZE + DNSCRYPT_QUERY_NONCE_SIZE]; |
| 96 | let encrypted_packet = &wrapped_packet[DNSCRYPT_QUERY_HEADER_SIZE..]; |
| 97 | |
| 98 | let dnscrypt_encryption_params = dnscrypt_encryption_params_set |
| 99 | .iter() |
| 100 | .find(|p| p.client_magic() == client_magic) |
| 101 | .ok_or_else(|| anyhow!("Client magic not found"))?; |
| 102 | |
| 103 | let mut nonce = [0u8; DNSCRYPT_FULL_NONCE_SIZE]; |
| 104 | nonce[..DNSCRYPT_QUERY_NONCE_SIZE].copy_from_slice(client_nonce); |
| 105 | |
| 106 | let cached_shared_key = { |
| 107 | let mut key_cache = dnscrypt_encryption_params |
| 108 | .key_cache |
| 109 | .as_ref() |
| 110 | .unwrap() |
| 111 | .lock(); |
| 112 | key_cache |
| 113 | .get(client_pk) |
| 114 | .map(|cached_shared_key| (*cached_shared_key).clone()) |
| 115 | }; |
| 116 | let shared_key = match cached_shared_key { |
| 117 | Some(cached_shared_key) => cached_shared_key, |
| 118 | None => { |
no test coverage detected