1use super::{Prehash, SignatureAnswer, SignatureMode, SignatureProvider};
4use crate::Octets;
5use core::cmp::Ordering;
6use structured_asn1::digest::{Digest, Resolution};
7use structured_asn1::{Encoding, Reader, memory::Work};
8use structured_pkix::algorithm::digest::{Algorithm, AsnDigest};
9use structured_pkix::{AlgorithmIdentifier, path::WorkingKey};
10
11#[derive(Debug)]
19pub struct ProviderSession<P> {
20 backend: P,
21 marker: u8,
22}
23
24impl<P> ProviderSession<P> {
25 #[must_use]
27 pub const fn new(backend: P) -> Self {
28 Self { backend, marker: 0 }
29 }
30 #[must_use]
32 pub const fn backend(&self) -> &P {
33 &self.backend
34 }
35 #[must_use]
37 pub fn same_session(&self, other: &Self) -> bool {
38 core::ptr::eq(
39 core::ptr::from_ref(&self.marker),
40 core::ptr::from_ref(&other.marker),
41 )
42 }
43}
44
45impl<P> core::ops::Deref for ProviderSession<P> {
46 type Target = P;
47 fn deref(&self) -> &P {
48 self.backend()
49 }
50}
51
52impl<'a, P: Digest<'a>> Digest<'a> for ProviderSession<P> {
53 type Identity = P::Identity;
54 type State = P::State;
55 type Output = P::Output;
56 type Error = P::Error;
57 fn width(&self, identity: &Self::Identity) -> Option<usize> {
58 self.backend.width(identity)
59 }
60 fn compare<W: Work>(
61 &self,
62 left: &Self::Identity,
63 right: &Self::Identity,
64 work: &W,
65 ) -> Result<Ordering, Self::Error> {
66 self.backend.compare(left, right, work)
67 }
68 fn start<W: Work>(
69 &'a self,
70 identity: &Self::Identity,
71 work: &W,
72 ) -> Result<Resolution<Self::State>, Self::Error> {
73 self.backend.start(identity, work)
74 }
75 fn update<W: Work>(
76 &self,
77 state: &mut Self::State,
78 bytes: &[u8],
79 work: &W,
80 ) -> Result<(), Self::Error> {
81 self.backend.update(state, bytes, work)
82 }
83 fn finish<W: Work>(&self, state: Self::State, work: &W) -> Result<Self::Output, Self::Error> {
84 self.backend.finish(state, work)
85 }
86 fn matches<W: Work>(
87 &self,
88 identity: &Self::Identity,
89 output: &Self::Output,
90 expected: &[u8],
91 work: &W,
92 ) -> Result<bool, Self::Error> {
93 self.backend.matches(identity, output, expected, work)
94 }
95}
96
97impl<'a, P: AsnDigest<'a>> AsnDigest<'a> for ProviderSession<P> {
98 fn identity(&self, algorithm: Algorithm) -> Option<Self::Identity> {
99 self.backend.identity(algorithm)
100 }
101}
102
103impl<'a, P: SignatureProvider<'a>> SignatureProvider<'a> for ProviderSession<P> {
104 type SignatureIdentity = P::SignatureIdentity;
105 type RawState = P::RawState;
106 fn resolve_signature(
107 &'a self,
108 algorithm: AlgorithmIdentifier<'a>,
109 digest: &Self::Identity,
110 key: WorkingKey<'a>,
111 encoding: Encoding,
112 parent: &Reader<'a>,
113 ) -> Result<Resolution<SignatureMode<Self::SignatureIdentity>>, Self::Error> {
114 self.backend
115 .resolve_signature(algorithm, digest, key, encoding, parent)
116 }
117 fn compare_signature<W: Work>(
118 &self,
119 left: &Self::SignatureIdentity,
120 right: &Self::SignatureIdentity,
121 work: &W,
122 ) -> Result<Ordering, Self::Error> {
123 self.backend.compare_signature(left, right, work)
124 }
125 fn start_raw<W: Work>(
126 &'a self,
127 identity: &Self::SignatureIdentity,
128 key: WorkingKey<'a>,
129 signature: &'a Octets<'a>,
130 work: &W,
131 ) -> Result<Self::RawState, Self::Error> {
132 self.backend.start_raw(identity, key, signature, work)
133 }
134 fn update_raw<W: Work>(
135 &self,
136 state: &mut Self::RawState,
137 bytes: &[u8],
138 work: &W,
139 ) -> Result<(), Self::Error> {
140 self.backend.update_raw(state, bytes, work)
141 }
142 fn finish_raw<W: Work>(
143 &self,
144 state: Self::RawState,
145 work: &W,
146 ) -> Result<SignatureAnswer, Self::Error> {
147 self.backend.finish_raw(state, work)
148 }
149 fn verify_prehashed<W: Work>(
150 &'a self,
151 identity: &Self::SignatureIdentity,
152 key: WorkingKey<'a>,
153 signature: &Octets<'a>,
154 digest: Prehash<'_, '_, Self, Self::Identity>,
155 work: &W,
156 ) -> Result<SignatureAnswer, Self::Error> {
157 self.backend.verify_prehashed(
158 identity,
159 key,
160 signature,
161 Prehash::new(&self.backend, digest.identity(), digest.as_bytes()),
162 work,
163 )
164 }
165}