• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BSSL_DER_PARSE_VALUES_H_
6 #define BSSL_DER_PARSE_VALUES_H_
7 
8 #include <stdint.h>
9 
10 #include <optional>
11 
12 #include <openssl/base.h>
13 
14 #include "input.h"
15 
16 BSSL_NAMESPACE_BEGIN
17 namespace der {
18 
19 // Reads a DER-encoded ASN.1 BOOLEAN value from |in| and puts the resulting
20 // value in |out|. Returns whether the encoded value could successfully be
21 // read.
22 [[nodiscard]] OPENSSL_EXPORT bool ParseBool(Input in, bool *out);
23 
24 // Like ParseBool, except it is more relaxed in what inputs it accepts: Any
25 // value that is a valid BER encoding will be parsed successfully.
26 [[nodiscard]] OPENSSL_EXPORT bool ParseBoolRelaxed(Input in, bool *out);
27 
28 // Checks the validity of a DER-encoded ASN.1 INTEGER value from |in|, and
29 // determines the sign of the number. Returns true on success and
30 // fills |negative|. Otherwise returns false and does not modify the out
31 // parameter.
32 //
33 //    in: The value portion of an INTEGER.
34 //    negative: Out parameter that is set to true if the number is negative
35 //        and false otherwise (zero is non-negative).
36 [[nodiscard]] OPENSSL_EXPORT bool IsValidInteger(Input in, bool *negative);
37 
38 // Reads a DER-encoded ASN.1 INTEGER value from |in| and puts the resulting
39 // value in |out|. ASN.1 INTEGERs are arbitrary precision; this function is
40 // provided as a convenience when the caller knows that the value is unsigned
41 // and is between 0 and 2^64-1. This function returns false if the value is too
42 // big to fit in a uint64_t, is negative, or if there is an error reading the
43 // integer.
44 [[nodiscard]] OPENSSL_EXPORT bool ParseUint64(Input in, uint64_t *out);
45 
46 // Same as ParseUint64() but for a uint8_t.
47 [[nodiscard]] OPENSSL_EXPORT bool ParseUint8(Input in, uint8_t *out);
48 
49 // The BitString class is a helper for representing a valid parsed BIT STRING.
50 //
51 // * The bits are ordered within each octet of bytes() from most to least
52 //   significant, as in the DER encoding.
53 //
54 // * There may be at most 7 unused bits.
55 class OPENSSL_EXPORT BitString {
56  public:
57   BitString() = default;
58 
59   // |unused_bits| represents the number of bits in the last octet of |bytes|,
60   // starting from the least significant bit, that are unused. It MUST be < 8.
61   // And if bytes is empty, then it MUST be 0.
62   BitString(Input bytes, uint8_t unused_bits);
63 
bytes()64   Input bytes() const { return bytes_; }
unused_bits()65   uint8_t unused_bits() const { return unused_bits_; }
66 
67   // Returns true if the bit string contains 1 at the specified position.
68   // Otherwise returns false.
69   //
70   // A return value of false can mean either:
71   //  * The bit value at |bit_index| is 0.
72   //  * There is no bit at |bit_index| (index is beyond the end).
73   [[nodiscard]] bool AssertsBit(size_t bit_index) const;
74 
75  private:
76   Input bytes_;
77   uint8_t unused_bits_ = 0;
78 
79   // Default assignment and copy constructor are OK.
80 };
81 
82 // Reads a DER-encoded ASN.1 BIT STRING value from |in| and returns the
83 // resulting octet string and number of unused bits.
84 //
85 // On failure, returns std::nullopt.
86 [[nodiscard]] OPENSSL_EXPORT std::optional<BitString> ParseBitString(Input in);
87 
88 struct OPENSSL_EXPORT GeneralizedTime {
89   uint16_t year;
90   uint8_t month;
91   uint8_t day;
92   uint8_t hours;
93   uint8_t minutes;
94   uint8_t seconds;
95 
96   // Returns true if the value is in UTCTime's range.
97   bool InUTCTimeRange() const;
98 };
99 
100 OPENSSL_EXPORT bool operator<(const GeneralizedTime &lhs,
101                               const GeneralizedTime &rhs);
102 OPENSSL_EXPORT bool operator<=(const GeneralizedTime &lhs,
103                                const GeneralizedTime &rhs);
104 OPENSSL_EXPORT bool operator>(const GeneralizedTime &lhs,
105                               const GeneralizedTime &rhs);
106 OPENSSL_EXPORT bool operator>=(const GeneralizedTime &lhs,
107                                const GeneralizedTime &rhs);
108 
109 // Reads a DER-encoded ASN.1 UTCTime value from |in| and puts the resulting
110 // value in |out|, returning true if the UTCTime could be parsed successfully.
111 [[nodiscard]] OPENSSL_EXPORT bool ParseUTCTime(Input in, GeneralizedTime *out);
112 
113 // Reads a DER-encoded ASN.1 GeneralizedTime value from |in| and puts the
114 // resulting value in |out|, returning true if the GeneralizedTime could
115 // be parsed successfully. This function is even more restrictive than the
116 // DER rules - it follows the rules from RFC5280, which does not allow for
117 // fractional seconds.
118 [[nodiscard]] OPENSSL_EXPORT bool ParseGeneralizedTime(Input in,
119                                                        GeneralizedTime *out);
120 
121 // Reads a DER-encoded ASN.1 IA5String value from |in| and stores the result in
122 // |out| as ASCII, returning true if successful.
123 [[nodiscard]] OPENSSL_EXPORT bool ParseIA5String(Input in, std::string *out);
124 
125 // Reads a DER-encoded ASN.1 VisibleString value from |in| and stores the result
126 // in |out| as ASCII, returning true if successful.
127 [[nodiscard]] OPENSSL_EXPORT bool ParseVisibleString(Input in,
128                                                      std::string *out);
129 
130 // Reads a DER-encoded ASN.1 PrintableString value from |in| and stores the
131 // result in |out| as ASCII, returning true if successful.
132 [[nodiscard]] OPENSSL_EXPORT bool ParsePrintableString(Input in,
133                                                        std::string *out);
134 
135 // Reads a DER-encoded ASN.1 TeletexString value from |in|, treating it as
136 // Latin-1, and stores the result in |out| as UTF-8, returning true if
137 // successful.
138 //
139 // This is for compatibility with legacy implementations that would use Latin-1
140 // encoding but tag it as TeletexString.
141 [[nodiscard]] OPENSSL_EXPORT bool ParseTeletexStringAsLatin1(Input in,
142                                                              std::string *out);
143 
144 // Reads a DER-encoded ASN.1 UniversalString value from |in| and stores the
145 // result in |out| as UTF-8, returning true if successful.
146 [[nodiscard]] OPENSSL_EXPORT bool ParseUniversalString(Input in,
147                                                        std::string *out);
148 
149 // Reads a DER-encoded ASN.1 BMPString value from |in| and stores the
150 // result in |out| as UTF-8, returning true if successful.
151 [[nodiscard]] OPENSSL_EXPORT bool ParseBmpString(Input in, std::string *out);
152 
153 }  // namespace der
154 BSSL_NAMESPACE_END
155 
156 #endif  // BSSL_DER_PARSE_VALUES_H_
157