Conditionally decrypt and un-serialize a python object. Detects whether the data was encrypted with AES or sent via TLS-only. Args: data: Data to decrypt and deserialize raw: Whether to return raw deserialized data nonce: Optional nonce
(self, data, raw=False, nonce=None, peer_cert=None, claimed_id=None)
| 2134 | return super().dumps(obj, nonce=nonce) |
| 2135 | |
| 2136 | def loads(self, data, raw=False, nonce=None, peer_cert=None, claimed_id=None): |
| 2137 | """ |
| 2138 | Conditionally decrypt and un-serialize a python object. |
| 2139 | |
| 2140 | Detects whether the data was encrypted with AES or sent via TLS-only. |
| 2141 | |
| 2142 | Args: |
| 2143 | data: Data to decrypt and deserialize |
| 2144 | raw: Whether to return raw deserialized data |
| 2145 | nonce: Optional nonce for verification |
| 2146 | peer_cert: Peer's SSL certificate (DER format bytes) |
| 2147 | claimed_id: The minion ID claimed in the message |
| 2148 | |
| 2149 | Returns: |
| 2150 | Deserialized python object |
| 2151 | """ |
| 2152 | import salt.transport.tls_util |
| 2153 | |
| 2154 | # Check if data has TLS marker (was sent without AES) |
| 2155 | if data.startswith(self.TLS_MARKER): |
| 2156 | # Verify TLS optimization is valid for this connection |
| 2157 | if not salt.transport.tls_util.can_skip_aes_encryption( |
| 2158 | self.opts, peer_cert=peer_cert, claimed_id=claimed_id |
| 2159 | ): |
| 2160 | log.warning( |
| 2161 | "Received TLS-optimized message but TLS requirements not met. Rejecting." |
| 2162 | ) |
| 2163 | return {} |
| 2164 | |
| 2165 | log.debug("TLS optimization: skipping AES decryption for %s", claimed_id) |
| 2166 | # Remove TLS marker |
| 2167 | data = data[len(self.TLS_MARKER) :] |
| 2168 | |
| 2169 | # Verify integrity marker |
| 2170 | if not data.startswith(self.PICKLE_PAD): |
| 2171 | return {} |
| 2172 | data = data[len(self.PICKLE_PAD) :] |
| 2173 | |
| 2174 | # Handle nonce if present |
| 2175 | if nonce: |
| 2176 | ret_nonce = data[:32].decode() |
| 2177 | data = data[32:] |
| 2178 | if ret_nonce != nonce: |
| 2179 | from salt.exceptions import SaltClientError |
| 2180 | |
| 2181 | raise SaltClientError( |
| 2182 | f"Nonce verification error {ret_nonce} {nonce}" |
| 2183 | ) |
| 2184 | |
| 2185 | # Deserialize payload |
| 2186 | payload = salt.payload.loads(data, raw=raw) |
| 2187 | |
| 2188 | # Handle serial number check |
| 2189 | if isinstance(payload, dict): |
| 2190 | if "serial" in payload: |
| 2191 | serial = payload.pop("serial") |
| 2192 | if serial <= self.serial: |
| 2193 | log.critical( |