summaryrefslogtreecommitdiffstats
path: root/vendor/spki/src/algorithm.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/spki/src/algorithm.rs
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/spki/src/algorithm.rs')
-rw-r--r--vendor/spki/src/algorithm.rs132
1 files changed, 132 insertions, 0 deletions
diff --git a/vendor/spki/src/algorithm.rs b/vendor/spki/src/algorithm.rs
new file mode 100644
index 000000000..2a8b6c7f9
--- /dev/null
+++ b/vendor/spki/src/algorithm.rs
@@ -0,0 +1,132 @@
+//! X.509 `AlgorithmIdentifier`
+
+use crate::{Error, Result};
+use core::cmp::Ordering;
+use der::asn1::{AnyRef, ObjectIdentifier};
+use der::{Decode, DecodeValue, DerOrd, Encode, Header, Reader, Sequence, ValueOrd};
+
+/// X.509 `AlgorithmIdentifier` as defined in [RFC 5280 Section 4.1.1.2].
+///
+/// ```text
+/// AlgorithmIdentifier ::= SEQUENCE {
+/// algorithm OBJECT IDENTIFIER,
+/// parameters ANY DEFINED BY algorithm OPTIONAL }
+/// ```
+///
+/// [RFC 5280 Section 4.1.1.2]: https://tools.ietf.org/html/rfc5280#section-4.1.1.2
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+pub struct AlgorithmIdentifier<'a> {
+ /// Algorithm OID, i.e. the `algorithm` field in the `AlgorithmIdentifier`
+ /// ASN.1 schema.
+ pub oid: ObjectIdentifier,
+
+ /// Algorithm `parameters`.
+ pub parameters: Option<AnyRef<'a>>,
+}
+
+impl<'a> AlgorithmIdentifier<'a> {
+ /// Assert the `algorithm` OID is an expected value.
+ pub fn assert_algorithm_oid(&self, expected_oid: ObjectIdentifier) -> Result<ObjectIdentifier> {
+ if self.oid == expected_oid {
+ Ok(expected_oid)
+ } else {
+ Err(Error::OidUnknown { oid: expected_oid })
+ }
+ }
+
+ /// Assert `parameters` is an OID and has the expected value.
+ pub fn assert_parameters_oid(
+ &self,
+ expected_oid: ObjectIdentifier,
+ ) -> Result<ObjectIdentifier> {
+ let actual_oid = self.parameters_oid()?;
+
+ if actual_oid == expected_oid {
+ Ok(actual_oid)
+ } else {
+ Err(Error::OidUnknown { oid: expected_oid })
+ }
+ }
+
+ /// Assert the values of the `algorithm` and `parameters` OIDs.
+ pub fn assert_oids(
+ &self,
+ algorithm: ObjectIdentifier,
+ parameters: ObjectIdentifier,
+ ) -> Result<()> {
+ self.assert_algorithm_oid(algorithm)?;
+ self.assert_parameters_oid(parameters)?;
+ Ok(())
+ }
+
+ /// Get the `parameters` field as an [`AnyRef`].
+ ///
+ /// Returns an error if `parameters` are `None`.
+ pub fn parameters_any(&self) -> Result<AnyRef<'a>> {
+ self.parameters.ok_or(Error::AlgorithmParametersMissing)
+ }
+
+ /// Get the `parameters` field as an [`ObjectIdentifier`].
+ ///
+ /// Returns an error if it is absent or not an OID.
+ pub fn parameters_oid(&self) -> Result<ObjectIdentifier> {
+ Ok(ObjectIdentifier::try_from(self.parameters_any()?)?)
+ }
+
+ /// Convert to a pair of [`ObjectIdentifier`]s.
+ ///
+ /// This method is helpful for decomposing in match statements. Note in
+ /// particular that `NULL` parameters are treated the same as missing
+ /// parameters.
+ ///
+ /// Returns an error if parameters are present but not an OID.
+ pub fn oids(&self) -> der::Result<(ObjectIdentifier, Option<ObjectIdentifier>)> {
+ Ok((
+ self.oid,
+ match self.parameters {
+ None => None,
+ Some(p) => match p {
+ AnyRef::NULL => None,
+ _ => Some(p.oid()?),
+ },
+ },
+ ))
+ }
+}
+
+impl<'a> DecodeValue<'a> for AlgorithmIdentifier<'a> {
+ fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
+ reader.read_nested(header.length, |reader| {
+ Ok(Self {
+ oid: reader.decode()?,
+ parameters: reader.decode()?,
+ })
+ })
+ }
+}
+
+impl<'a> Sequence<'a> for AlgorithmIdentifier<'a> {
+ fn fields<F, T>(&self, f: F) -> der::Result<T>
+ where
+ F: FnOnce(&[&dyn Encode]) -> der::Result<T>,
+ {
+ f(&[&self.oid, &self.parameters])
+ }
+}
+
+impl<'a> TryFrom<&'a [u8]> for AlgorithmIdentifier<'a> {
+ type Error = Error;
+
+ fn try_from(bytes: &'a [u8]) -> Result<Self> {
+ Ok(Self::from_der(bytes)?)
+ }
+}
+
+impl ValueOrd for AlgorithmIdentifier<'_> {
+ fn value_cmp(&self, other: &Self) -> der::Result<Ordering> {
+ match self.oid.der_cmp(&other.oid)? {
+ Ordering::Equal => self.parameters.der_cmp(&other.parameters),
+ other => Ok(other),
+ }
+ }
+}