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