Decrypt the payload using a key ring (supports dual-key rotation). `epoch` must come from the on-disk segment preamble. `preamble_bytes` must match the preamble bytes written at the start of this segment.
(
&self,
epoch: &[u8; 4],
preamble_bytes: Option<&[u8; PREAMBLE_SIZE]>,
ring: Option<&crate::crypto::KeyRing>,
)
| 132 | /// `epoch` must come from the on-disk segment preamble. `preamble_bytes` |
| 133 | /// must match the preamble bytes written at the start of this segment. |
| 134 | pub fn decrypt_payload_ring( |
| 135 | &self, |
| 136 | epoch: &[u8; 4], |
| 137 | preamble_bytes: Option<&[u8; PREAMBLE_SIZE]>, |
| 138 | ring: Option<&crate::crypto::KeyRing>, |
| 139 | ) -> Result<Vec<u8>> { |
| 140 | if !self.is_encrypted() { |
| 141 | return Ok(self.payload.clone()); |
| 142 | } |
| 143 | |
| 144 | let ring = ring.ok_or_else(|| WalError::EncryptionError { |
| 145 | detail: "record is encrypted but no decryption key ring provided".into(), |
| 146 | })?; |
| 147 | |
| 148 | let mut aad_header = self.header; |
| 149 | aad_header.record_type &= !ENCRYPTED_FLAG; |
| 150 | aad_header.payload_len = 0; |
| 151 | aad_header.crc32c = 0; |
| 152 | let header_bytes = aad_header.to_bytes(); |
| 153 | let aad = build_aad(preamble_bytes, &header_bytes); |
| 154 | |
| 155 | ring.decrypt_aad(epoch, self.header.lsn, &aad, &self.payload) |
| 156 | } |
| 157 | |
| 158 | /// Whether this record's payload is encrypted. |
| 159 | pub fn is_encrypted(&self) -> bool { |