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