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