Coverage Report

Created: 2025-12-28 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/yasna-0.5.2/src/writer/mod.rs
Line
Count
Source
1
// Copyright 2016 Masaki Hara
2
// Copyright 2019 Fortanix, Inc.
3
//
4
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7
// option. This file may not be copied, modified, or distributed
8
// except according to those terms.
9
10
#![forbid(missing_docs)]
11
12
use alloc::vec::Vec;
13
14
#[cfg(feature = "num-bigint")]
15
use num_bigint::{BigUint, BigInt};
16
#[cfg(feature = "bit-vec")]
17
use bit_vec::BitVec;
18
19
use super::{PCBit, Tag};
20
use super::tags::{TAG_BOOLEAN,TAG_INTEGER,TAG_OCTETSTRING};
21
use super::tags::{TAG_NULL,TAG_OID,TAG_UTF8STRING,TAG_SEQUENCE,TAG_SET,TAG_ENUM,TAG_IA5STRING,TAG_BMPSTRING};
22
use super::tags::{TAG_NUMERICSTRING,TAG_PRINTABLESTRING,TAG_VISIBLESTRING};
23
use super::models::{ObjectIdentifier,TaggedDerValue};
24
#[cfg(feature = "time")]
25
use super::models::{UTCTime,GeneralizedTime};
26
27
/// Constructs DER-encoded data as `Vec<u8>`.
28
///
29
/// This function uses the loan pattern: `callback` is called back with
30
/// a [`DERWriter`], to which the ASN.1 value is written.
31
///
32
/// # Examples
33
///
34
/// ```
35
/// use yasna;
36
/// let der = yasna::construct_der(|writer| {
37
///     writer.write_sequence(|writer| {
38
///         writer.next().write_i64(10);
39
///         writer.next().write_bool(true);
40
///     })
41
/// });
42
/// assert_eq!(der, vec![48, 6, 2, 1, 10, 1, 1, 255]);
43
/// ```
44
0
pub fn construct_der<F>(callback: F) -> Vec<u8>
45
0
        where F: FnOnce(DERWriter) {
46
0
    let mut buf = Vec::new();
47
0
    {
48
0
        let mut writer = DERWriterSeq {
49
0
            buf: &mut buf,
50
0
        };
51
0
        callback(writer.next());
52
0
    }
53
0
    return buf;
54
0
}
Unexecuted instantiation: yasna::writer::construct_der::<<rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: yasna::writer::construct_der::<<rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: yasna::writer::construct_der::<<rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}::{closure#1}>
Unexecuted instantiation: yasna::writer::construct_der::<rcgen::write_x509_authority_key_identifier::{closure#0}>
Unexecuted instantiation: yasna::writer::construct_der::<<rcgen::certificate::CertificateParams>::write_key_usage::{closure#0}>
Unexecuted instantiation: yasna::writer::construct_der::<<rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}>
Unexecuted instantiation: yasna::writer::construct_der::<<rcgen::certificate::CertificateParams>::write_extended_key_usage::{closure#0}>
Unexecuted instantiation: yasna::writer::construct_der::<<rcgen::certificate::CustomExtension>::new_acme_identifier::{closure#0}>
Unexecuted instantiation: yasna::writer::construct_der::<<rcgen::key_pair::KeyPair as rcgen::key_pair::PublicKeyData>::subject_public_key_info::{closure#0}>
Unexecuted instantiation: yasna::writer::construct_der::<_>
55
56
/// Tries to construct DER-encoded data as `Vec<u8>`.
57
///
58
/// Same as [`construct_der`], only that it allows
59
/// returning an error from the passed closure.
60
///
61
/// This function uses the loan pattern: `callback` is called back with
62
/// a [`DERWriterSeq`], to which the ASN.1 values are written.
63
///
64
/// # Examples
65
///
66
/// ```
67
/// use yasna;
68
/// let res_ok = yasna::try_construct_der::<_, ()>(|writer| {
69
///     writer.write_sequence(|writer| {
70
///         writer.next().write_i64(10);
71
///         writer.next().write_bool(true);
72
///     });
73
///     Ok(())
74
/// });
75
/// let res_err = yasna::try_construct_der::<_, &str>(|writer| {
76
///     writer.write_sequence(|writer| {
77
///         writer.next().write_i64(10);
78
///         writer.next().write_bool(true);
79
///         return Err("some error here");
80
///     })?;
81
///     Ok(())
82
/// });
83
/// assert_eq!(res_ok, Ok(vec![48, 6, 2, 1, 10, 1, 1, 255]));
84
/// assert_eq!(res_err, Err("some error here"));
85
/// ```
86
0
pub fn try_construct_der<F, E>(callback: F) -> Result<Vec<u8>, E>
87
0
        where F: FnOnce(DERWriter) -> Result<(), E> {
88
0
    let mut buf = Vec::new();
89
    {
90
0
        let mut writer = DERWriterSeq {
91
0
            buf: &mut buf,
92
0
        };
93
0
        callback(writer.next())?;
94
    }
95
0
    return Ok(buf);
96
0
}
Unexecuted instantiation: yasna::writer::try_construct_der::<rcgen::key_pair::sign_der<rcgen::key_pair::KeyPair, <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}>::{closure#0}, rcgen::error::Error>
Unexecuted instantiation: yasna::writer::try_construct_der::<rcgen::key_pair::sign_der<rcgen::key_pair::KeyPair, <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}>::{closure#0}::{closure#0}::{closure#0}, rcgen::error::Error>
Unexecuted instantiation: yasna::writer::try_construct_der::<_, _>
97
98
/// Constructs DER-encoded sequence of data as `Vec<u8>`.
99
///
100
/// This is similar to [`construct_der`], but this function
101
/// accepts more than one ASN.1 values.
102
///
103
/// This function uses the loan pattern: `callback` is called back with
104
/// a [`DERWriterSeq`], to which the ASN.1 values are written.
105
///
106
/// # Examples
107
///
108
/// ```
109
/// use yasna;
110
/// let der = yasna::construct_der_seq(|writer| {
111
///     writer.next().write_i64(10);
112
///     writer.next().write_bool(true);
113
/// });
114
/// assert_eq!(der, vec![2, 1, 10, 1, 1, 255]);
115
/// ```
116
0
pub fn construct_der_seq<F>(callback: F) -> Vec<u8>
117
0
        where F: FnOnce(&mut DERWriterSeq) {
118
0
    let mut buf = Vec::new();
119
0
    {
120
0
        let mut writer = DERWriterSeq {
121
0
            buf: &mut buf,
122
0
        };
123
0
        callback(&mut writer);
124
0
    }
125
0
    return buf;
126
0
}
127
128
/// Tries to construct a DER-encoded sequence of data as `Vec<u8>`.
129
///
130
/// Same as [`construct_der_seq`], only that it allows
131
/// returning an error from the passed closure.
132
///
133
/// This function uses the loan pattern: `callback` is called back with
134
/// a [`DERWriterSeq`], to which the ASN.1 values are written.
135
///
136
/// # Examples
137
///
138
/// ```
139
/// use yasna;
140
/// let res_ok = yasna::try_construct_der_seq::<_, ()>(|writer| {
141
///     writer.next().write_i64(10);
142
///     writer.next().write_bool(true);
143
///     Ok(())
144
/// });
145
/// let res_err = yasna::try_construct_der_seq::<_, &str>(|writer| {
146
///     return Err("some error here");
147
/// });
148
/// assert_eq!(res_ok, Ok(vec![2, 1, 10, 1, 1, 255]));
149
/// assert_eq!(res_err, Err("some error here"));
150
/// ```
151
0
pub fn try_construct_der_seq<F, E>(callback: F) -> Result<Vec<u8> , E>
152
0
        where F: FnOnce(&mut DERWriterSeq) -> Result<(), E> {
153
0
    let mut buf = Vec::new();
154
    {
155
0
        let mut writer = DERWriterSeq {
156
0
            buf: &mut buf,
157
0
        };
158
0
        callback(&mut writer)?;
159
    }
160
0
    return Ok(buf);
161
0
}
162
163
/// A writer object that accepts an ASN.1 value.
164
///
165
/// The two main sources of `DERWriterSeq` are:
166
///
167
/// - The [`construct_der`] function, the starting point of
168
///   DER serialization.
169
/// - The [`next`](DERWriterSeq::next) method of [`DERWriterSeq`].
170
///
171
/// # Examples
172
///
173
/// ```
174
/// use yasna;
175
/// let der = yasna::construct_der(|writer| {
176
///     writer.write_i64(10)
177
/// });
178
/// assert_eq!(der, vec![2, 1, 10]);
179
/// ```
180
#[derive(Debug)]
181
pub struct DERWriter<'a> {
182
    buf: &'a mut Vec<u8>,
183
    implicit_tag: Option<Tag>,
184
}
185
186
impl<'a> DERWriter<'a> {
187
0
    fn from_buf(buf: &'a mut Vec<u8>) -> Self {
188
0
        return DERWriter {
189
0
            buf,
190
0
            implicit_tag: None,
191
0
        }
192
0
    }
193
    /// Writes BER identifier (tag + primitive/constructed) octets.
194
0
    fn write_identifier(&mut self, tag: Tag, pc: PCBit) {
195
0
        let tag = if let Some(tag) = self.implicit_tag { tag } else { tag };
196
0
        self.implicit_tag = None;
197
0
        let classid = tag.tag_class as u8;
198
0
        let pcid = pc as u8;
199
0
        if tag.tag_number < 31 {
200
0
            self.buf.push(
201
0
                (classid << 6) | (pcid << 5) | (tag.tag_number as u8));
202
0
            return;
203
0
        }
204
0
        self.buf.push((classid << 6) | (pcid << 5) | 31);
205
0
        let mut shiftnum = 63; // ceil(64 / 7) * 7 - 7
206
0
        while (tag.tag_number >> shiftnum) == 0 {
207
0
            shiftnum -= 7;
208
0
        }
209
0
        while shiftnum > 0 {
210
0
            self.buf.push(128 | (((tag.tag_number >> shiftnum) & 127) as u8));
211
0
            shiftnum -= 7;
212
0
        }
213
0
        self.buf.push((tag.tag_number & 127) as u8);
214
0
    }
215
216
    /// Writes BER length octets.
217
0
    fn write_length(&mut self, length: usize) {
218
0
        let length = length as u64;
219
0
        if length < 128 {
220
0
            self.buf.push(length as u8);
221
0
            return;
222
0
        }
223
0
        let mut shiftnum = 56; // ceil(64 / 8) * 8 - 8
224
0
        while (length >> shiftnum) == 0 {
225
0
            shiftnum -= 8;
226
0
        }
227
0
        self.buf.push(128 | ((shiftnum / 8 + 1) as u8));
228
        loop {
229
0
            self.buf.push((length >> shiftnum) as u8);
230
0
            if shiftnum == 0 {
231
0
                break;
232
0
            }
233
0
            shiftnum -= 8;
234
        }
235
0
    }
236
237
    /// Deals with unknown length procedures.
238
    /// This function first marks the current position and
239
    /// allocates 3 bytes. Then it calls back `callback`.
240
    /// It then calculates the length and moves the written data
241
    /// to the actual position. Finally, it writes the length.
242
0
    fn with_length<T, F>(&mut self, callback: F) -> T
243
0
        where F: FnOnce(&mut Self) -> T {
244
0
        let expected_length_length = 3;
245
0
        for _ in 0..3 {
246
0
            self.buf.push(255);
247
0
        }
248
0
        let start_pos = self.buf.len();
249
0
        let result = callback(self);
250
0
        let length = (self.buf.len() - start_pos) as u64;
251
        let length_length;
252
0
        let mut shiftnum = 56; // ceil(64 / 8) * 8 - 8
253
0
        if length < 128 {
254
0
            length_length = 1;
255
0
        } else {
256
0
            while (length >> shiftnum) == 0 {
257
0
                shiftnum -= 8;
258
0
            }
259
0
            length_length = shiftnum / 8 + 2;
260
        }
261
        let new_start_pos;
262
0
        if length_length < expected_length_length {
263
0
            let diff = expected_length_length - length_length;
264
0
            new_start_pos = start_pos - diff;
265
0
            self.buf.drain(new_start_pos .. start_pos);
266
0
        } else if length_length > expected_length_length {
267
0
            let diff = length_length - expected_length_length;
268
0
            new_start_pos = start_pos + diff;
269
0
            for _ in 0..diff { self.buf.insert(start_pos, 0); }
270
0
        } else {
271
0
            new_start_pos = start_pos;
272
0
        }
273
0
        let mut idx = new_start_pos - length_length;
274
0
        if length < 128 {
275
0
            self.buf[idx] = length as u8;
276
0
        } else {
277
0
            self.buf[idx] = 128 | ((shiftnum / 8 + 1) as u8);
278
0
            idx += 1;
279
            loop {
280
0
                self.buf[idx] = (length >> shiftnum) as u8;
281
0
                idx += 1;
282
0
                if shiftnum == 0 {
283
0
                    break;
284
0
                }
285
0
                shiftnum -= 8;
286
            }
287
        }
288
0
        return result;
289
0
    }
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<core::result::Result<(), rcgen::error::Error>, <yasna::writer::DERWriter>::write_sequence<core::result::Result<(), rcgen::error::Error>, <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<core::result::Result<(), rcgen::error::Error>, <yasna::writer::DERWriter>::write_sequence<core::result::Result<(), rcgen::error::Error>, rcgen::key_pair::sign_der<rcgen::key_pair::KeyPair, <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}>::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_tagged<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_tagged<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#2}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_tagged<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#1}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_tagged<(), <rcgen::OtherNameValue>::write_der::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_x509_extension<<rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_x509_extension<<rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}::{closure#1}>::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_x509_extension<rcgen::write_x509_authority_key_identifier::{closure#0}>::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_key_usage::{closure#0}>::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}>::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_extended_key_usage::{closure#0}>::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::key_pair::serialize_public_key_der<rcgen::key_pair::KeyPair>::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::crl::write_distribution_point_name_uris<&alloc::vec::Vec<alloc::string::String>>::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::crl::write_distribution_point_name_uris<&alloc::vec::Vec<alloc::string::String>>::{closure#0}::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#1}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#1}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::certificate::write_general_subtrees::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_x509_authority_key_identifier::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::certificate::CertificateParams>::write_extended_key_usage::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::certificate::write_general_subtrees::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), rcgen::write_distinguished_name::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::crl::CrlDistributionPoint>::write_der::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::crl::CrlIssuingDistributionPoint>::write_der::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::crl::RevokedCertParams>::write_der::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::sign_algo::SignatureAlgorithm>::write_alg_ident::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<(), <yasna::writer::DERWriter>::write_sequence<(), <rcgen::sign_algo::SignatureAlgorithm>::write_oids_sign_alg::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::with_length::<_, _>
290
291
    /// Writes `bool` as an ASN.1 BOOLEAN value.
292
    ///
293
    /// # Examples
294
    ///
295
    /// ```
296
    /// use yasna;
297
    /// let der = yasna::construct_der(|writer| {
298
    ///     writer.write_bool(true)
299
    /// });
300
    /// assert_eq!(der, vec![1, 1, 255]);
301
    /// ```
302
0
    pub fn write_bool(mut self, val: bool) {
303
0
        self.write_identifier(TAG_BOOLEAN, PCBit::Primitive);
304
0
        self.write_length(1);
305
0
        self.buf.push(if val { 255 } else { 0 });
306
0
    }
307
308
0
    fn write_integer(mut self, tag: Tag, val: i64) {
309
0
        let mut shiftnum = 56;
310
0
        while shiftnum > 0 &&
311
0
                (val >> (shiftnum-1) == 0 || val >> (shiftnum-1) == -1) {
312
0
            shiftnum -= 8;
313
0
        }
314
0
        self.write_identifier(tag, PCBit::Primitive);
315
0
        self.write_length(shiftnum / 8 + 1);
316
        loop {
317
0
            self.buf.push((val >> shiftnum) as u8);
318
0
            if shiftnum == 0 {
319
0
                break;
320
0
            }
321
0
            shiftnum -= 8;
322
        }
323
0
    }
324
325
    /// Writes `i64` as an ASN.1 ENUMERATED value.
326
    ///
327
    /// # Examples
328
    ///
329
    /// ```
330
    /// use yasna;
331
    /// let der = yasna::construct_der(|writer| {
332
    ///     writer.write_enum(2)
333
    /// });
334
    /// assert_eq!(der, vec![10, 1, 2]);
335
    /// ```
336
0
    pub fn write_enum(self, val: i64) {
337
0
        self.write_integer(TAG_ENUM, val);
338
0
    }
339
340
    /// Writes `i64` as an ASN.1 INTEGER value.
341
    ///
342
    /// # Examples
343
    ///
344
    /// ```
345
    /// use yasna;
346
    /// let der = yasna::construct_der(|writer| {
347
    ///     writer.write_i64(1234567890)
348
    /// });
349
    /// assert_eq!(der, vec![2, 4, 73, 150, 2, 210]);
350
    /// ```
351
0
    pub fn write_i64(self, val: i64) {
352
0
        self.write_integer(TAG_INTEGER, val);
353
0
    }
354
355
    /// Writes `u64` as an ASN.1 INTEGER value.
356
0
    pub fn write_u64(mut self, val: u64) {
357
0
        let mut shiftnum = 64;
358
0
        while shiftnum > 0 && val >> (shiftnum-1) == 0 {
359
0
            shiftnum -= 8;
360
0
        }
361
0
        self.write_identifier(TAG_INTEGER, PCBit::Primitive);
362
0
        self.write_length(shiftnum / 8 + 1);
363
0
        if shiftnum == 64 {
364
0
            self.buf.push(0);
365
0
            shiftnum -= 8;
366
0
        }
367
        loop {
368
0
            self.buf.push((val >> shiftnum) as u8);
369
0
            if shiftnum == 0 {
370
0
                break;
371
0
            }
372
0
            shiftnum -= 8;
373
        }
374
0
    }
375
376
    /// Writes `i32` as an ASN.1 INTEGER value.
377
0
    pub fn write_i32(self, val: i32) {
378
0
        self.write_i64(val as i64)
379
0
    }
380
381
    /// Writes `u32` as an ASN.1 INTEGER value.
382
0
    pub fn write_u32(self, val: u32) {
383
0
        self.write_i64(val as i64)
384
0
    }
385
386
    /// Writes `i16` as an ASN.1 INTEGER value.
387
0
    pub fn write_i16(self, val: i16) {
388
0
        self.write_i64(val as i64)
389
0
    }
390
391
    /// Writes `u16` as an ASN.1 INTEGER value.
392
0
    pub fn write_u16(self, val: u16) {
393
0
        self.write_i64(val as i64)
394
0
    }
395
396
    /// Writes `i8` as an ASN.1 INTEGER value.
397
0
    pub fn write_i8(self, val: i8) {
398
0
        self.write_i64(val as i64)
399
0
    }
400
401
    /// Writes `u8` as an ASN.1 INTEGER value.
402
0
    pub fn write_u8(self, val: u8) {
403
0
        self.write_i64(val as i64)
404
0
    }
405
406
    #[cfg(feature = "num-bigint")]
407
    /// Writes `BigInt` as an ASN.1 INTEGER value.
408
    ///
409
    /// # Examples
410
    ///
411
    /// ```
412
    /// # fn main() {
413
    /// use yasna;
414
    /// use num_bigint::BigInt;
415
    /// let der = yasna::construct_der(|writer| {
416
    ///     writer.write_bigint(
417
    ///         &BigInt::parse_bytes(b"1234567890", 10).unwrap())
418
    /// });
419
    /// assert_eq!(der, vec![2, 4, 73, 150, 2, 210]);
420
    /// # }
421
    /// ```
422
    ///
423
    /// # Features
424
    ///
425
    /// This method is enabled by `num` feature.
426
    ///
427
    /// ```toml
428
    /// [dependencies]
429
    /// yasna = { version = "*", features = ["num-bigint"] }
430
    /// ```
431
    pub fn write_bigint(self, val: &BigInt) {
432
        use num_bigint::Sign;
433
        let (sign, mut bytes) = val.to_bytes_be();
434
        if sign == Sign::Minus {
435
            let mut carry: usize = 1;
436
            for b in bytes.iter_mut().rev() {
437
                let bval = 255 - (*b as usize);
438
                *b = (bval + carry) as u8;
439
                carry = (bval + carry) >> 8;
440
            }
441
        }
442
        self.write_bigint_bytes(&bytes, sign != Sign::Minus);
443
    }
444
445
    /// Writes `&[u8]` and `bool` as an ASN.1 INTEGER value.
446
    ///
447
    /// The first parameter encodes the bytes of the integer, in big-endian
448
    /// byte ordering and two's complement format. The second parameter encodes
449
    /// the sign, and is true if the number is non-negative, and false if it is
450
    /// negative. Zero is encoded by passing an empty slice.
451
    ///
452
    /// The number is expected to be in two's complement format, so for example
453
    /// `1` is encoded as `[1]` and `-1` as `[255]`.
454
    ///
455
    /// You don't have to worry about leading bits, meaning that if the leading
456
    /// bit of a positive number is not zero, a leading zero byte will be
457
    /// encoded by the function. Similarly, if the leading bit of a negative
458
    /// number is not one, a leading byte will be added by the function as well.
459
    ///
460
    /// # Examples
461
    ///
462
    /// ```
463
    /// # fn main() {
464
    /// use yasna;
465
    /// let der = yasna::construct_der(|writer| {
466
    ///     // Encodes 1234567890
467
    ///     writer.write_bigint_bytes(&[73, 150, 2, 210], true)
468
    /// });
469
    /// assert_eq!(der, vec![2, 4, 73, 150, 2, 210]);
470
    /// # }
471
    /// ```
472
0
    pub fn write_bigint_bytes(mut self, bytes: &[u8], positive: bool) {
473
0
        let mut bytes = bytes;
474
475
        // Remove leading zero bytes
476
0
        while bytes.get(0) == Some(&0)  {
477
0
            bytes = &bytes[1..];
478
0
        }
479
480
0
        if !positive {
481
            // Remove leading 255 bytes
482
            // (the order is important here, [255, 0] should be a fixpoint input)
483
0
            while bytes.len() > 1 && bytes[0] == 255 && bytes.get(1).unwrap_or(&0) & 128 != 0 {
484
0
                bytes = &bytes[1..];
485
0
            }
486
0
        }
487
488
0
        self.write_identifier(TAG_INTEGER, PCBit::Primitive);
489
0
        if bytes.len() == 0 || bytes[0] == 0 {
490
0
            self.write_length(1);
491
0
            self.buf.push(0);
492
0
        } else if positive {
493
0
            if bytes[0] >= 128 {
494
0
                self.write_length(bytes.len() + 1);
495
0
                self.buf.push(0);
496
0
            } else {
497
0
                self.write_length(bytes.len());
498
0
            }
499
0
            self.buf.extend_from_slice(&bytes);
500
        } else {
501
0
            debug_assert!(bytes[0] != 0);
502
0
            if bytes[0] < 128 {
503
0
                self.write_length(bytes.len() + 1);
504
0
                self.buf.push(255);
505
0
            } else {
506
0
                self.write_length(bytes.len());
507
0
            }
508
0
            self.buf.extend_from_slice(&bytes);
509
        }
510
0
    }
511
512
    #[cfg(feature = "num-bigint")]
513
    /// Writes `BigUint` as an ASN.1 INTEGER value.
514
    ///
515
    /// # Examples
516
    ///
517
    /// ```
518
    /// # fn main() {
519
    /// use yasna;
520
    /// use num_bigint::BigUint;
521
    /// let der = yasna::construct_der(|writer| {
522
    ///     writer.write_biguint(
523
    ///         &BigUint::parse_bytes(b"1234567890", 10).unwrap())
524
    /// });
525
    /// assert_eq!(der, vec![2, 4, 73, 150, 2, 210]);
526
    /// # }
527
    /// ```
528
    ///
529
    /// # Features
530
    ///
531
    /// This method is enabled by `num` feature.
532
    ///
533
    /// ```toml
534
    /// [dependencies]
535
    /// yasna = { version = "*", features = ["num-bigint"] }
536
    /// ```
537
    pub fn write_biguint(mut self, val: &BigUint) {
538
        self.write_identifier(TAG_INTEGER, PCBit::Primitive);
539
        let mut bytes = val.to_bytes_le();
540
        if &bytes == &[0] {
541
            self.write_length(1);
542
            self.buf.push(0);
543
            return;
544
        }
545
        let byteslen = bytes.len();
546
        debug_assert!(bytes[byteslen-1] != 0);
547
        if bytes[byteslen-1] >= 128 {
548
            self.write_length(byteslen+1);
549
            self.buf.push(0);
550
        } else {
551
            self.write_length(byteslen);
552
        }
553
        bytes.reverse();
554
        self.buf.extend_from_slice(&bytes);
555
    }
556
557
    #[cfg(feature = "bit-vec")]
558
    /// Writes [`BitVec`] as an ASN.1 BITSTRING value.
559
    ///
560
    /// # Examples
561
    ///
562
    /// ```
563
    /// # fn main() {
564
    /// use yasna;
565
    /// use bit_vec::BitVec;
566
    /// let der = yasna::construct_der(|writer| {
567
    ///     writer.write_bitvec(&
568
    ///         [1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1,
569
    ///             0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1]
570
    ///         .iter().map(|&i| i != 0).collect())
571
    /// });
572
    /// assert_eq!(&der, &[3, 5, 3, 206, 213, 116, 24]);
573
    /// # }
574
    /// ```
575
    ///
576
    /// # Features
577
    ///
578
    /// This method is enabled by `bit-vec` feature.
579
    ///
580
    /// ```toml
581
    /// [dependencies]
582
    /// yasna = { version = "*", features = ["bit-vec"] }
583
    /// ```
584
    pub fn write_bitvec(self, bitvec: &BitVec) {
585
        let len = bitvec.len();
586
        let bytes = bitvec.to_bytes();
587
        self.write_bitvec_bytes(&bytes, len);
588
    }
589
590
    /// Writes `&[u8]` and `usize` as an ASN.1 BITSTRING value.
591
    ///
592
    /// The `len` parameter represents the number of bits to be encoded.
593
    /// This function is similar to `write_bitvec`, with `to_bytes` applied to
594
    /// the bitvec, but is available even if the `bit-vec` feature is disabled.
595
    ///
596
    /// # Examples
597
    ///
598
    /// ```
599
    /// # fn main() {
600
    /// use yasna;
601
    /// let der_1 = yasna::construct_der(|writer| {
602
    ///     writer.write_bitvec_bytes(&[117, 13, 64], 18)
603
    /// });
604
    /// let der_2 = yasna::construct_der(|writer| {
605
    ///     writer.write_bitvec_bytes(&[117, 13, 65], 18)
606
    /// });
607
    /// assert_eq!(&der_1, &[3, 4, 6, 117, 13, 64]);
608
    /// assert_eq!(&der_2, &[3, 4, 6, 117, 13, 64]);
609
    /// # }
610
    /// ```
611
0
    pub fn write_bitvec_bytes(mut self, bytes: &[u8], len: usize) {
612
        use super::tags::TAG_BITSTRING;
613
0
        self.write_identifier(TAG_BITSTRING, PCBit::Primitive);
614
0
        debug_assert!(len <= 8 * bytes.len());
615
0
        debug_assert!(8 * bytes.len() < len + 8);
616
0
        self.write_length(1 + bytes.len());
617
0
        let len_diff = 8 * bytes.len() - len;
618
0
        self.buf.push(len_diff as u8);
619
0
        if bytes.len() > 0 {
620
0
            self.buf.extend_from_slice(&bytes[0 .. bytes.len() - 1]);
621
0
            let mask = !(255u16 >> (8 - len_diff)) as u8;
622
0
            self.buf.push(bytes[bytes.len() - 1] & mask);
623
0
        }
624
0
    }
625
626
    /// Writes `&[u8]` as an ASN.1 OCTETSTRING value.
627
    ///
628
    /// # Examples
629
    ///
630
    /// ```
631
    /// use yasna;
632
    /// let der = yasna::construct_der(|writer| {
633
    ///     writer.write_bytes(b"Hello!")
634
    /// });
635
    /// assert_eq!(der, vec![4, 6, 72, 101, 108, 108, 111, 33]);
636
    /// ```
637
0
    pub fn write_bytes(mut self, bytes: &[u8]) {
638
0
        self.write_identifier(TAG_OCTETSTRING, PCBit::Primitive);
639
0
        self.write_length(bytes.len());
640
0
        self.buf.extend_from_slice(bytes);
641
0
    }
642
643
    /// Writes `&str` as an ASN.1 UTF8String value.
644
    ///
645
    /// # Examples
646
    ///
647
    /// ```
648
    /// use yasna;
649
    /// let der = yasna::construct_der(|writer| {
650
    ///     writer.write_utf8_string("Hello!")
651
    /// });
652
    /// assert_eq!(der, vec![12, 6, 72, 101, 108, 108, 111, 33]);
653
    /// ```
654
0
    pub fn write_utf8_string(mut self, string: &str) {
655
0
        self.write_identifier(TAG_UTF8STRING, PCBit::Primitive);
656
0
        self.write_length(string.len());
657
0
        self.buf.extend_from_slice(string.as_bytes());
658
0
    }
659
660
    /// Writes `&str` as an ASN.1 IA5String value.
661
    ///
662
    /// # Examples
663
    ///
664
    /// ```
665
    /// use yasna;
666
    /// let der = yasna::construct_der(|writer| {
667
    ///     writer.write_ia5_string("Hello!")
668
    /// });
669
    /// assert_eq!(der, vec![22, 6, 72, 101, 108, 108, 111, 33]);
670
    /// ```
671
0
    pub fn write_ia5_string(mut self, string: &str) {
672
0
        assert!(string.is_ascii(), "IA5 string must be ASCII");
673
0
        self.write_identifier(TAG_IA5STRING, PCBit::Primitive);
674
0
        self.write_length(string.len());
675
0
        self.buf.extend_from_slice(string.as_bytes());
676
0
    }
677
678
    /// Writes `&str` as an ASN.1 BMPString value.
679
    ///
680
    /// # Examples
681
    ///
682
    /// ```
683
    /// use yasna;
684
    /// let der = yasna::construct_der(|writer| {
685
    ///     writer.write_bmp_string("❤πü2?")
686
    /// });
687
    /// assert_eq!(der, vec![30, 10, 39, 100, 3, 192, 0, 252, 0, 50, 0, 63]);
688
    /// ```
689
0
    pub fn write_bmp_string(mut self, string: &str) {
690
0
        let utf16 : Vec<u16> = string.encode_utf16().collect();
691
692
0
        let mut bytes = Vec::with_capacity(utf16.len() * 2);
693
0
        for c in utf16 {
694
0
            bytes.push((c / 256) as u8);
695
0
            bytes.push((c % 256) as u8);
696
0
        }
697
698
0
        self.write_identifier(TAG_BMPSTRING, PCBit::Primitive);
699
0
        self.write_length(bytes.len());
700
0
        self.buf.extend_from_slice(&bytes);
701
0
    }
702
703
    /// Writes the ASN.1 NULL value.
704
    ///
705
    /// # Examples
706
    ///
707
    /// ```
708
    /// use yasna;
709
    /// let der = yasna::construct_der(|writer| {
710
    ///     writer.write_null()
711
    /// });
712
    /// assert_eq!(der, vec![5, 0]);
713
    /// ```
714
0
    pub fn write_null(mut self) {
715
0
        self.write_identifier(TAG_NULL, PCBit::Primitive);
716
0
        self.write_length(0);
717
0
    }
718
719
    /// Writes an ASN.1 object identifier.
720
    ///
721
    /// # Examples
722
    ///
723
    /// ```
724
    /// use yasna;
725
    /// use yasna::models::ObjectIdentifier;
726
    /// let der = yasna::construct_der(|writer| {
727
    ///     writer.write_oid(&ObjectIdentifier::from_slice(
728
    ///         &[1, 2, 840, 113549, 1, 1]))
729
    /// });
730
    /// assert_eq!(&der, &[6, 8, 42, 134, 72, 134, 247, 13, 1, 1]);
731
    /// ```
732
    ///
733
    /// # Panics
734
    ///
735
    /// It panics when the OID cannot be canonically encoded in BER.
736
0
    pub fn write_oid(mut self, oid: &ObjectIdentifier) {
737
0
        assert!(oid.components().len() >= 2, "Invalid OID: too short");
738
0
        let id0 = oid.components()[0];
739
0
        let id1 = oid.components()[1];
740
0
        assert!(
741
0
            (id0 < 3) && (id1 < 18446744073709551535) &&
742
0
            (id0 >= 2 || id1 < 40),
743
0
            "Invalid OID {{{} {} ...}}", id0, id1);
744
0
        let subid0 = id0 * 40 + id1;
745
0
        let mut length = 0;
746
0
        for i in 1..oid.components().len() {
747
0
            let mut subid = if i == 1 {
748
0
                subid0
749
            } else {
750
0
                oid.components()[i]
751
            } | 1;
752
0
            while subid > 0 {
753
0
                length += 1;
754
0
                subid >>= 7;
755
0
            }
756
        }
757
0
        self.write_identifier(TAG_OID, PCBit::Primitive);
758
0
        self.write_length(length);
759
0
        for i in 1..oid.components().len() {
760
0
            let subid = if i == 1 {
761
0
                subid0
762
            } else {
763
0
                oid.components()[i]
764
            };
765
0
            let mut shiftnum = 63; // ceil(64 / 7) * 7 - 7
766
0
            while ((subid|1) >> shiftnum) == 0 {
767
0
                shiftnum -= 7;
768
0
            }
769
0
            while shiftnum > 0 {
770
0
                self.buf.push(128 | ((((subid|1) >> shiftnum) & 127) as u8));
771
0
                shiftnum -= 7;
772
0
            }
773
0
            self.buf.push((subid & 127) as u8);
774
        }
775
0
    }
776
777
    /// Writes an ASN.1 UTF8String.
778
    ///
779
    /// # Examples
780
    ///
781
    /// ```
782
    /// use yasna;
783
    /// let der = yasna::construct_der(|writer| {
784
    ///     writer.write_utf8string("gnaw ροκανίζω 𪘂る")
785
    /// });
786
    /// assert_eq!(&der, &[
787
    ///     12, 29, 103, 110, 97, 119, 32, 207, 129, 206, 191, 206,
788
    ///     186, 206, 177, 206, 189, 206, 175, 206, 182, 207,
789
    ///     137, 32, 240, 170, 152, 130, 227, 130, 139]);
790
    /// ```
791
0
    pub fn write_utf8string(self, string: &str) {
792
0
        self.write_tagged_implicit(TAG_UTF8STRING, |writer| {
793
0
            writer.write_bytes(string.as_bytes())
794
0
        })
795
0
    }
796
797
    /// Writes ASN.1 SEQUENCE.
798
    ///
799
    /// This function uses the loan pattern: `callback` is called back with
800
    /// a [`DERWriterSeq`], to which the contents of the
801
    /// SEQUENCE is written.
802
    ///
803
    /// This is equivalent to [`write_sequence_of`](Self::write_sequence_of)
804
    /// in behavior.
805
    ///
806
    /// # Examples
807
    ///
808
    /// ```
809
    /// use yasna;
810
    /// let der = yasna::construct_der(|writer| {
811
    ///     writer.write_sequence(|writer| {
812
    ///         writer.next().write_i64(10);
813
    ///         writer.next().write_bool(true);
814
    ///     })
815
    /// });
816
    /// assert_eq!(der, vec![48, 6, 2, 1, 10, 1, 1, 255]);
817
    /// ```
818
0
    pub fn write_sequence<T, F>(mut self, callback: F) -> T
819
0
        where F: FnOnce(&mut DERWriterSeq) -> T {
820
0
        self.write_identifier(TAG_SEQUENCE, PCBit::Constructed);
821
0
        return self.with_length(|writer| {
822
0
            callback(&mut DERWriterSeq {
823
0
                buf: writer.buf,
824
0
            })
825
0
        });
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<core::result::Result<(), rcgen::error::Error>, <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<core::result::Result<(), rcgen::error::Error>, rcgen::key_pair::sign_der<rcgen::key_pair::KeyPair, <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}>::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}::{closure#0}::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}::{closure#1}>::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<rcgen::write_x509_authority_key_identifier::{closure#0}>::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_key_usage::{closure#0}>::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}>::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_extended_key_usage::{closure#0}>::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::key_pair::serialize_public_key_der<rcgen::key_pair::KeyPair>::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::crl::write_distribution_point_name_uris<&alloc::vec::Vec<alloc::string::String>>::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::crl::write_distribution_point_name_uris<&alloc::vec::Vec<alloc::string::String>>::{closure#0}::{closure#0}::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}::{closure#0}::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#1}::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#1}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::certificate::write_general_subtrees::{closure#0}::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_authority_key_identifier::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_extended_key_usage::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::certificate::write_general_subtrees::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_distinguished_name::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::crl::CrlDistributionPoint>::write_der::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::crl::CrlIssuingDistributionPoint>::write_der::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::crl::RevokedCertParams>::write_der::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_alg_ident::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_oids_sign_alg::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<_, _>::{closure#0}
826
0
    }
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<core::result::Result<(), rcgen::error::Error>, <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<core::result::Result<(), rcgen::error::Error>, rcgen::key_pair::sign_der<rcgen::key_pair::KeyPair, <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}>::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}::{closure#1}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<rcgen::write_x509_authority_key_identifier::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_key_usage::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_extension<<rcgen::certificate::CertificateParams>::write_extended_key_usage::{closure#0}>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::key_pair::serialize_public_key_der<rcgen::key_pair::KeyPair>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::crl::write_distribution_point_name_uris<&alloc::vec::Vec<alloc::string::String>>::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::crl::write_distribution_point_name_uris<&alloc::vec::Vec<alloc::string::String>>::{closure#0}::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#1}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#1}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::certificate::write_general_subtrees::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_x509_authority_key_identifier::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_extended_key_usage::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::crl::RevokedCertParams>::write_der::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::certificate::write_general_subtrees::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), rcgen::write_distinguished_name::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::crl::CrlDistributionPoint>::write_der::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::crl::CrlIssuingDistributionPoint>::write_der::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::crl::RevokedCertParams>::write_der::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_alg_ident::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_oids_sign_alg::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_sequence::<_, _>
827
828
    /// Writes ASN.1 SEQUENCE OF.
829
    ///
830
    /// This function uses the loan pattern: `callback` is called back with
831
    /// a [`DERWriterSeq`], to which the contents of the
832
    /// SEQUENCE OF are written.
833
    ///
834
    /// This is equivalent to [`write_sequence`](Self::write_sequence) in
835
    /// behavior.
836
    ///
837
    /// # Examples
838
    ///
839
    /// ```
840
    /// use yasna;
841
    /// let der = yasna::construct_der(|writer| {
842
    ///     writer.write_sequence_of(|writer| {
843
    ///         for &i in &[10, -129] {
844
    ///             writer.next().write_i64(i);
845
    ///         }
846
    ///     })
847
    /// });
848
    /// assert_eq!(der, vec![48, 7, 2, 1, 10, 2, 2, 255, 127]);
849
    /// ```
850
0
    pub fn write_sequence_of<T, F>(self, callback: F) -> T
851
0
        where F: FnOnce(&mut DERWriterSeq) -> T {
852
0
        self.write_sequence(callback)
853
0
    }
854
855
    /// Writes ASN.1 SET.
856
    ///
857
    /// This function uses the loan pattern: `callback` is called back with
858
    /// a [`DERWriterSet`], to which the contents of the
859
    /// SET are written.
860
    ///
861
    /// For SET OF values, use [`write_set_of`](Self::write_set_of) instead.
862
    ///
863
    /// # Examples
864
    ///
865
    /// ```
866
    /// use yasna;
867
    /// let der = yasna::construct_der(|writer| {
868
    ///     writer.write_set(|writer| {
869
    ///         writer.next().write_i64(10);
870
    ///         writer.next().write_bool(true);
871
    ///     })
872
    /// });
873
    /// assert_eq!(der, vec![49, 6, 1, 1, 255, 2, 1, 10]);
874
    /// ```
875
0
    pub fn write_set<T, F>(mut self, callback: F) -> T
876
0
        where F: FnOnce(&mut DERWriterSet) -> T {
877
0
        let mut bufs = Vec::new();
878
0
        let result = callback(&mut DERWriterSet {
879
0
            bufs: &mut bufs,
880
0
        });
881
0
        for buf in bufs.iter() {
882
0
            assert!(buf.len() > 0, "Empty output in write_set()");
883
        }
884
0
        bufs.sort_by(|buf0, buf1| {
885
0
            let buf00 = buf0[0] & 223;
886
0
            let buf10 = buf1[0] & 223;
887
0
            if buf00 != buf10 || (buf0[0] & 31) != 31 {
888
0
                return buf00.cmp(&buf10);
889
0
            }
890
0
            let len0 = buf0[1..].iter().position(|x| x & 128 == 0).unwrap();
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}>::{closure#0}::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}>::{closure#0}::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<_, _>::{closure#0}::{closure#0}
891
0
            let len1 = buf1[1..].iter().position(|x| x & 128 == 0).unwrap();
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}>::{closure#0}::{closure#1}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}>::{closure#0}::{closure#1}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<_, _>::{closure#0}::{closure#1}
892
0
            if len0 != len1 {
893
0
                return len0.cmp(&len1);
894
0
            }
895
0
            return buf0[1..].cmp(&buf1[1..]);
896
0
        });
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<_, _>::{closure#0}
897
        // let bufs_len = bufs.iter().map(|buf| buf.len()).sum();
898
0
        let bufs_len = bufs.iter().map(|buf| buf.len()).fold(0, |x, y| x + y);
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}>::{closure#1}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}>::{closure#1}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<_, _>::{closure#1}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}>::{closure#2}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}>::{closure#2}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<_, _>::{closure#2}
899
0
        self.write_identifier(TAG_SET, PCBit::Constructed);
900
0
        self.write_length(bufs_len);
901
0
        for buf in bufs.iter() {
902
0
            self.buf.extend_from_slice(buf);
903
0
        }
904
0
        return result;
905
0
    }
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<(), <rcgen::certificate::CertificateParams>::write_extension_request_attribute::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set::<_, _>
906
907
    /// Writes ASN.1 SET OF.
908
    ///
909
    /// This function uses the loan pattern: `callback` is called back with
910
    /// a [`DERWriterSet`], to which the contents of the
911
    /// SET OF are written.
912
    ///
913
    /// For SET values, use [`write_set`](Self::write_set) instead.
914
    ///
915
    /// # Examples
916
    ///
917
    /// ```
918
    /// use yasna;
919
    /// let der = yasna::construct_der(|writer| {
920
    ///     writer.write_set_of(|writer| {
921
    ///         for &i in &[10, -129] {
922
    ///             writer.next().write_i64(i);
923
    ///         }
924
    ///     })
925
    /// });
926
    /// assert_eq!(der, vec![49, 7, 2, 1, 10, 2, 2, 255, 127]);
927
    /// ```
928
0
    pub fn write_set_of<T, F>(mut self, callback: F) -> T
929
0
        where F: FnOnce(&mut DERWriterSet) -> T {
930
0
        let mut bufs = Vec::new();
931
0
        let result = callback(&mut DERWriterSet {
932
0
            bufs: &mut bufs,
933
0
        });
934
0
        for buf in bufs.iter() {
935
0
            assert!(buf.len() > 0, "Empty output in write_set_of()");
936
        }
937
0
        bufs.sort();
938
        // let bufs_len = bufs.iter().map(|buf| buf.len()).sum();
939
0
        let bufs_len = bufs.iter().map(|buf| buf.len()).fold(0, |x, y| x + y);
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set_of::<(), <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set_of::<_, _>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set_of::<(), <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}::{closure#0}::{closure#0}>::{closure#1}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set_of::<_, _>::{closure#1}
940
0
        self.write_identifier(TAG_SET, PCBit::Constructed);
941
0
        self.write_length(bufs_len);
942
0
        for buf in bufs.iter() {
943
0
            self.buf.extend_from_slice(buf);
944
0
        }
945
0
        return result;
946
0
    }
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set_of::<(), <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_set_of::<_, _>
947
948
    /// Writes an ASN.1 NumericString.
949
    ///
950
    /// # Examples
951
    ///
952
    /// ```
953
    /// use yasna;
954
    /// let der = yasna::construct_der(|writer| {
955
    ///     writer.write_numeric_string("128 256")
956
    /// });
957
    /// assert_eq!(&der, &[18, 7, 49, 50, 56, 32, 50, 53, 54]);
958
    /// ```
959
0
    pub fn write_numeric_string(self, string: &str) {
960
0
        let bytes = string.as_bytes();
961
0
        for &byte in bytes {
962
0
            assert!(byte == b' ' || (b'0' <= byte && byte <= b'9'),
963
0
                "Invalid NumericString: {:?} appeared", byte);
964
        }
965
0
        self.write_tagged_implicit(TAG_NUMERICSTRING, |writer| {
966
0
            writer.write_bytes(bytes)
967
0
        });
968
0
    }
969
970
    /// Writes an ASN.1 PrintableString.
971
    ///
972
    /// # Examples
973
    ///
974
    /// ```
975
    /// use yasna;
976
    /// let der = yasna::construct_der(|writer| {
977
    ///     writer.write_printable_string("Co., Ltd.")
978
    /// });
979
    /// assert_eq!(&der, &[19, 9, 67, 111, 46, 44, 32, 76, 116, 100, 46]);
980
    /// ```
981
0
    pub fn write_printable_string(self, string: &str) {
982
0
        let bytes = string.as_bytes();
983
0
        for &byte in bytes {
984
0
            assert!(
985
0
                byte == b' ' ||
986
0
                (b'\'' <= byte && byte <= b':' && byte != b'*') ||
987
0
                byte == b'=' ||
988
0
                (b'A' <= byte && byte <= b'Z') ||
989
0
                (b'a' <= byte && byte <= b'z'),
990
0
                "Invalid PrintableString: {:?} appeared", byte);
991
        }
992
0
        self.write_tagged_implicit(TAG_PRINTABLESTRING, |writer| {
993
0
            writer.write_bytes(bytes)
994
0
        });
995
0
    }
996
997
    #[cfg(feature = "time")]
998
    /// Writes an ASN.1 UTCTime.
999
    ///
1000
    /// # Examples
1001
    ///
1002
    /// ```
1003
    /// # fn main() {
1004
    /// use yasna;
1005
    /// use yasna::models::UTCTime;
1006
    /// use time::OffsetDateTime;
1007
    /// let der = yasna::construct_der(|writer| {
1008
    ///     writer.write_utctime(
1009
    ///         &UTCTime::from_datetime(
1010
    ///             OffsetDateTime::from_unix_timestamp(378820800).unwrap()))
1011
    /// });
1012
    /// assert_eq!(&der, &[
1013
    ///     23, 13, 56, 50, 48, 49, 48, 50, 49, 50, 48, 48, 48, 48, 90]);
1014
    /// # }
1015
    /// ```
1016
    ///
1017
    /// # Features
1018
    ///
1019
    /// This method is enabled by `time` feature.
1020
    ///
1021
    /// ```toml
1022
    /// [dependencies]
1023
    /// yasna = { version = "*", features = ["time"] }
1024
    /// ```
1025
0
    pub fn write_utctime(self, datetime: &UTCTime) {
1026
        use super::tags::TAG_UTCTIME;
1027
0
        self.write_tagged_implicit(TAG_UTCTIME, |writer| {
1028
0
            writer.write_bytes(&datetime.to_bytes())
1029
0
        });
1030
0
    }
1031
1032
    #[cfg(feature = "time")]
1033
    /// Writes an ASN.1 GeneralizedTime.
1034
    ///
1035
    /// # Examples
1036
    ///
1037
    /// ```
1038
    /// # fn main() {
1039
    /// use yasna;
1040
    /// use yasna::models::GeneralizedTime;
1041
    /// use time::OffsetDateTime;
1042
    /// let der = yasna::construct_der(|writer| {
1043
    ///     writer.write_generalized_time(
1044
    ///         &GeneralizedTime::from_datetime(
1045
    ///             OffsetDateTime::from_unix_timestamp_nanos(
1046
    ///                 500_159_309_724_000_000).unwrap()))
1047
    /// });
1048
    /// assert_eq!(&der, &[
1049
    ///     24, 19, 49, 57, 56, 53, 49, 49, 48, 54, 50,
1050
    ///     49, 48, 56, 50, 57, 46, 55, 50, 52, 90]);
1051
    /// # }
1052
    /// ```
1053
    ///
1054
    /// # Features
1055
    ///
1056
    /// This method is enabled by `time` feature.
1057
    ///
1058
    /// ```toml
1059
    /// [dependencies]
1060
    /// yasna = { version = "*", features = ["time"] }
1061
    /// ```
1062
0
    pub fn write_generalized_time(self, datetime: &GeneralizedTime) {
1063
        use super::tags::TAG_GENERALIZEDTIME;
1064
0
        self.write_tagged_implicit(TAG_GENERALIZEDTIME, |writer| {
1065
0
            writer.write_bytes(&datetime.to_bytes())
1066
0
        });
1067
0
    }
1068
1069
    /// Writes an ASN.1 VisibleString.
1070
    ///
1071
    /// # Examples
1072
    ///
1073
    /// ```
1074
    /// use yasna;
1075
    /// let der = yasna::construct_der(|writer| {
1076
    ///     writer.write_visible_string("Hi!")
1077
    /// });
1078
    /// assert_eq!(&der, &[26, 3, 72, 105, 33]);
1079
    /// ```
1080
0
    pub fn write_visible_string(self, string: &str) {
1081
0
        let bytes = string.as_bytes();
1082
0
        for &byte in bytes {
1083
0
            assert!(b' ' <= byte && byte <= b'~',
1084
0
                "Invalid VisibleString: {:?} appeared", byte);
1085
        }
1086
0
        self.write_tagged_implicit(TAG_VISIBLESTRING, |writer| {
1087
0
            writer.write_bytes(bytes)
1088
0
        });
1089
0
    }
1090
1091
    /// Writes an (explicitly) tagged value.
1092
    ///
1093
    /// # Examples
1094
    ///
1095
    /// ```
1096
    /// use yasna::{self,Tag};
1097
    /// let der = yasna::construct_der(|writer| {
1098
    ///     writer.write_tagged(Tag::context(3), |writer| {
1099
    ///         writer.write_i64(10)
1100
    ///     })
1101
    /// });
1102
    /// assert_eq!(der, vec![163, 3, 2, 1, 10]);
1103
    /// ```
1104
    ///
1105
    /// Note: you can achieve the same using
1106
    /// [`write_tagged_implicit`](Self::write_tagged_implicit):
1107
    ///
1108
    /// ```
1109
    /// use yasna::{self,Tag};
1110
    /// let der = yasna::construct_der(|writer| {
1111
    ///     writer.write_tagged_implicit(Tag::context(3), |writer| {
1112
    ///         writer.write_sequence(|writer| {
1113
    ///             let writer = writer.next();
1114
    ///             writer.write_i64(10)
1115
    ///         })
1116
    ///     })
1117
    /// });
1118
    /// assert_eq!(der, vec![163, 3, 2, 1, 10]);
1119
    /// ```
1120
0
    pub fn write_tagged<T, F>(mut self, tag: Tag, callback: F) -> T
1121
0
        where F: FnOnce(DERWriter) -> T {
1122
0
        self.write_identifier(tag, PCBit::Constructed);
1123
0
        return self.with_length(|writer| {
1124
0
            callback(DERWriter::from_buf(writer.buf))
1125
0
        });
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#2}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#1}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<(), <rcgen::OtherNameValue>::write_der::{closure#0}>::{closure#0}
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<_, _>::{closure#0}
1126
0
    }
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#2}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<(), <rcgen::sign_algo::SignatureAlgorithm>::write_params::{closure#0}::{closure#1}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<(), <rcgen::OtherNameValue>::write_der::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged::<_, _>
1127
1128
    /// Writes an implicitly tagged value.
1129
    ///
1130
    /// # Examples
1131
    ///
1132
    /// ```
1133
    /// use yasna::{self,Tag};
1134
    /// let der = yasna::construct_der(|writer| {
1135
    ///     writer.write_tagged_implicit(Tag::context(3), |writer| {
1136
    ///         writer.write_i64(10)
1137
    ///     })
1138
    /// });
1139
    /// assert_eq!(der, vec![131, 1, 10]);
1140
    /// ```
1141
0
    pub fn write_tagged_implicit<T, F>
1142
0
        (mut self, tag: Tag, callback: F) -> T
1143
0
        where F: FnOnce(DERWriter) -> T {
1144
0
        let tag = if let Some(tag) = self.implicit_tag { tag } else { tag };
1145
0
        self.implicit_tag = None;
1146
0
        let mut writer = DERWriter::from_buf(self.buf);
1147
0
        writer.implicit_tag = Some(tag);
1148
0
        return callback(writer);
1149
0
    }
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), <rcgen::certificate::CertificateParams>::serialize_request_with_attributes<rcgen::key_pair::KeyPair>::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), rcgen::crl::write_distribution_point_name_uris<&alloc::vec::Vec<alloc::string::String>>::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), rcgen::crl::write_distribution_point_name_uris<&alloc::vec::Vec<alloc::string::String>>::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), rcgen::crl::write_distribution_point_name_uris<&alloc::vec::Vec<alloc::string::String>>::{closure#0}::{closure#0}::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}::{closure#0}::{closure#2}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), rcgen::write_distinguished_name::{closure#0}::{closure#0}::{closure#0}::{closure#1}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), rcgen::certificate::write_general_subtrees::{closure#0}::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), rcgen::write_x509_authority_key_identifier::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), <rcgen::certificate::CertificateParams>::write_subject_alt_names::{closure#0}::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), <rcgen::crl::CrlIssuingDistributionPoint>::write_der::{closure#0}::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), rcgen::certificate::write_general_subtrees::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), <yasna::writer::DERWriter>::write_utctime::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), <yasna::writer::DERWriter>::write_utf8string::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), <yasna::writer::DERWriter>::write_numeric_string::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), <yasna::writer::DERWriter>::write_visible_string::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), <yasna::writer::DERWriter>::write_generalized_time::{closure#0}>
Unexecuted instantiation: <yasna::writer::DERWriter>::write_tagged_implicit::<(), <yasna::writer::DERWriter>::write_printable_string::{closure#0}>
1150
1151
    /// Writes the arbitrary tagged DER value in `der`.
1152
    ///
1153
    /// # Examples
1154
    ///
1155
    /// ```
1156
    /// use yasna;
1157
    /// use yasna::models::TaggedDerValue;
1158
    /// use yasna::tags::TAG_OCTETSTRING;
1159
    /// let tagged_der_value = TaggedDerValue::from_tag_and_bytes(TAG_OCTETSTRING, b"Hello!".to_vec());
1160
    /// let der1 = yasna::construct_der(|writer| {
1161
    ///     writer.write_tagged_der(&tagged_der_value)
1162
    /// });
1163
    /// let der2 = yasna::construct_der(|writer| {
1164
    ///     writer.write_bytes(b"Hello!")
1165
    /// });
1166
    /// assert_eq!(der1, der2);
1167
    /// ```
1168
0
    pub fn write_tagged_der(mut self, der: &TaggedDerValue) {
1169
0
        self.write_identifier(der.tag(), der.pcbit());
1170
0
        self.write_length(der.value().len());
1171
0
        self.buf.extend_from_slice(der.value());
1172
0
    }
1173
1174
    /// Writes `&[u8]` into the DER output buffer directly. Properly encoded tag
1175
    /// and length must be included at the start of the passed buffer.
1176
    ///
1177
    /// # Examples
1178
    ///
1179
    /// ```
1180
    /// use yasna;
1181
    /// let raw_der = yasna::construct_der(|writer| {
1182
    ///     writer.write_der(b"\x04\x06Hello!")
1183
    /// });
1184
    /// let der = yasna::construct_der(|writer| {
1185
    ///     writer.write_bytes(b"Hello!")
1186
    /// });
1187
    /// assert_eq!(raw_der, der);
1188
    /// ```
1189
0
    pub fn write_der(self, der: &[u8]) {
1190
0
        self.buf.extend_from_slice(der);
1191
0
    }
1192
}
1193
1194
/// A writer object that accepts ASN.1 values.
1195
///
1196
/// The main source of this object is the [`write_sequence`][write_sequence]
1197
/// method from [`DERWriter`].
1198
///
1199
/// [write_sequence]: DERWriter::write_sequence
1200
///
1201
/// # Examples
1202
///
1203
/// ```
1204
/// use yasna;
1205
/// let der = yasna::construct_der(|writer| {
1206
///     writer.write_sequence(|writer : &mut yasna::DERWriterSeq| {
1207
///         writer.next().write_i64(10);
1208
///         writer.next().write_bool(true);
1209
///     })
1210
/// });
1211
/// assert_eq!(der, vec![48, 6, 2, 1, 10, 1, 1, 255]);
1212
/// ```
1213
#[derive(Debug)]
1214
pub struct DERWriterSeq<'a> {
1215
    buf: &'a mut Vec<u8>,
1216
}
1217
1218
impl<'a> DERWriterSeq<'a> {
1219
    /// Generates a new [`DERWriter`].
1220
0
    pub fn next<'b>(&'b mut self) -> DERWriter<'b> {
1221
0
        return DERWriter::from_buf(self.buf);
1222
0
    }
1223
}
1224
1225
/// A writer object that accepts ASN.1 values.
1226
///
1227
/// The main source of this object is the [`write_set`](DERWriter::write_set)
1228
/// method from [`DERWriter`].
1229
///
1230
/// # Examples
1231
///
1232
/// ```
1233
/// use yasna;
1234
/// let der = yasna::construct_der(|writer| {
1235
///     writer.write_set(|writer : &mut yasna::DERWriterSet| {
1236
///         writer.next().write_i64(10);
1237
///         writer.next().write_bool(true);
1238
///     })
1239
/// });
1240
/// assert_eq!(der, vec![49, 6, 1, 1, 255, 2, 1, 10]);
1241
/// ```
1242
#[derive(Debug)]
1243
pub struct DERWriterSet<'a> {
1244
    bufs: &'a mut Vec<Vec<u8>>,
1245
}
1246
1247
impl<'a> DERWriterSet<'a> {
1248
    /// Generates a new [`DERWriter`].
1249
0
    pub fn next<'b>(&'b mut self) -> DERWriter<'b> {
1250
0
        self.bufs.push(Vec::new());
1251
0
        return DERWriter::from_buf(self.bufs.last_mut().unwrap());
1252
0
    }
1253
}
1254
1255
#[cfg(test)]
1256
mod tests;