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