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