structured_xades/material/
index.rs1use super::{Opaque, Placement, Value, View};
4use crate::timestamp::CarriedMaterial;
5use crate::xml::{Access, Xml};
6use crate::{ISSUER, Xades};
7use structured_asn1::memory::Work;
8use structured_ltv::material::{
9 self as ltv, ArtifactRef, ArtifactSource, CarriedOrigin, IndexError,
10};
11
12pub type Index<'source, N, D, G, W> =
15 ltv::Index<'source, N, D, G, Placement<N>, Opaque<N, D, G>, W, Xades>;
16pub type Occurrence<N, D, G> = ltv::Occurrence<N, D, G, Placement<N>>;
18pub type Archived<N, D, G> = ltv::Archived<N, D, G, Placement<N>>;
20
21pub type IndexResult<'source, X, W> = Result<
23 Index<'source, <X as Xml>::Id, <X as Xml>::Document, <X as Xml>::Generation, W>,
24 IndexError<<X as Xml>::Id>,
25>;
26
27pub fn index<'source, X: Xml, W: Work>(
51 view: &View<'source, X::Id, X::Document, X::Generation>,
52 access: &Access<'_, X, W>,
53) -> IndexResult<'source, X, W> {
54 let signature = view.signature;
55 if view.snapshot != access.snapshot() {
56 return Err(IndexError::Foreign { signature });
57 }
58 let mut index = Index::new(ISSUER, signature, view.opaque(), access)?;
59 let mut next_basic = 0;
60 for ordinal in 0..view.values.len() {
61 index.admit(access)?;
62 let value = &view.values[ordinal];
63 let placement = view.sources[ordinal].placement();
64 let artifact = match &value.value {
65 Value::Certificate(value) => ArtifactRef::Certificate(value),
66 Value::Crl(value) => ArtifactRef::Crl(value),
67 Value::Ocsp(_) => {
68 if let Some(basic) = view.basic.get(next_basic)
69 && basic.source_index() == ordinal
70 {
71 index.insert(
72 ISSUER,
73 ArtifactRef::Ocsp(basic.response()),
74 Occurrence::new(
75 ArtifactSource::Material(basic.source_index()),
76 basic.location(),
77 placement,
78 ),
79 access,
80 )?;
81 next_basic += 1;
82 }
83 continue;
84 }
85 };
86 index.insert(
87 ISSUER,
88 artifact,
89 Occurrence::new(ArtifactSource::Material(ordinal), value.location, placement),
90 access,
91 )?;
92 }
93 index.admit(access)?;
94 Ok(index)
95}
96
97pub fn index_with_tokens<'source, X: Xml, W: Work>(
103 view: &View<'source, X::Id, X::Document, X::Generation>,
104 material: &CarriedMaterial<'source, X::Id, X::Document, X::Generation>,
105 access: &Access<'_, X, W>,
106) -> IndexResult<'source, X, W> {
107 if material.view.snapshot() != view.snapshot {
108 return Err(IndexError::Foreign {
109 signature: view.signature,
110 });
111 }
112 if !access
113 .equal_id(material.view.signature(), view.signature)
114 .map_err(|cause| IndexError::Resource {
115 signature: view.signature,
116 cause,
117 })?
118 {
119 return Err(IndexError::Foreign {
120 signature: view.signature,
121 });
122 }
123 let mut index = index(view, access)?;
124 index.admit(access)?;
127 for token in 0..material.view.readings().len() {
128 index.admit(access)?;
129 let source = &material.view.sources()[token];
130 let placement = Placement::TimestampToken {
131 property: source.property(),
132 token: source.location().node,
133 role: source.role(),
134 };
135 let certificates = material.view.readings()[token]
136 .token()
137 .message()
138 .certificates();
139 for (certificate, value) in certificates.iter().enumerate() {
140 index.admit(access)?;
141 index.insert(
142 ISSUER,
143 ArtifactRef::Certificate(value),
144 Occurrence::new(
145 ArtifactSource::TokenCertificate { token, certificate },
146 source.location(),
147 placement,
148 ),
149 access,
150 )?;
151 }
152 }
153 for value in material.crls() {
154 index.admit(access)?;
155 index.insert(
156 ISSUER,
157 ArtifactRef::Crl(&value.value),
158 carried(material, value.origin),
159 access,
160 )?;
161 }
162 for value in material.basic_responses() {
163 index.admit(access)?;
164 index.insert(
165 ISSUER,
166 ArtifactRef::Ocsp(&value.value),
167 carried(material, value.origin),
168 access,
169 )?;
170 }
171 index.admit(access)?;
172 Ok(index)
173}
174
175fn carried<N: Copy, D: Copy, G: Copy>(
176 material: &CarriedMaterial<'_, N, D, G>,
177 origin: CarriedOrigin,
178) -> Occurrence<N, D, G> {
179 let source = &material.view.sources()[origin.token];
180 Occurrence::new(
181 ArtifactSource::TokenRevocation(origin),
182 source.location(),
183 Placement::TimestampToken {
184 property: source.property(),
185 token: source.location().node,
186 role: source.role(),
187 },
188 )
189}