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