use std::io::{self, Write};
use super::{CommandTokenError, RuntimeTokenClaims};
pub const MAX_RUNTIME_TOKEN_PAYLOAD_BYTES: usize = 64 * 1024;
pub const MAX_RUNTIME_TOKEN_SIGNATURE_BYTES: usize = 256 * 1024;
pub const MAX_RUNTIME_TOKEN_BYTES: usize =
4 + 2 * (MAX_RUNTIME_TOKEN_PAYLOAD_BYTES + MAX_RUNTIME_TOKEN_SIGNATURE_BYTES);
pub(super) fn validate_fields(fields: &[Option<&str>]) -> Result<(), CommandTokenError> {
let mut remaining = MAX_RUNTIME_TOKEN_PAYLOAD_BYTES;
for field in fields.iter().flatten() {
remaining = remaining
.checked_sub(field.len())
.ok_or(CommandTokenError::InvalidFormat)?;
}
Ok(())
}
pub(super) fn validate_signature(signature: &[u8]) -> Result<(), CommandTokenError> {
if signature.is_empty() || signature.len() > MAX_RUNTIME_TOKEN_SIGNATURE_BYTES {
return Err(CommandTokenError::InvalidFormat);
}
Ok(())
}
pub(super) fn serialize(claims: &RuntimeTokenClaims) -> Result<Vec<u8>, serde_json::Error> {
let mut writer = ClaimsWriter(Vec::new());
serde_json::to_writer(&mut writer, claims)?;
Ok(writer.0)
}
struct ClaimsWriter(Vec<u8>);
impl Write for ClaimsWriter {
fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
if bytes.len() > MAX_RUNTIME_TOKEN_PAYLOAD_BYTES - self.0.len() {
return Err(io::Error::other("Runtime token claims exceed byte limit"));
}
self.0.extend_from_slice(bytes);
Ok(bytes.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}