• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.35
/src/lib/asn1/asn1_str.cpp
1
/*
2
* Simple ASN.1 String Types
3
* (C) 1999-2007,2020 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/asn1_obj.h>
9

10
#include <botan/ber_dec.h>
11
#include <botan/der_enc.h>
12
#include <botan/internal/charset.h>
13
#include <botan/internal/ct_utils.h>
14
#include <botan/internal/fmt.h>
15

16
namespace Botan {
17

18
namespace {
19

20
/*
21
* Choose an encoding for the string
22
*/
23
ASN1_Type choose_encoding(std::string_view str) {
113,181✔
24
   auto all_printable = CT::Mask<uint8_t>::set();
113,181✔
25

26
   for(size_t i = 0; i != str.size(); ++i) {
122,177✔
27
      const uint8_t c = static_cast<uint8_t>(str[i]);
8,996✔
28

29
      auto is_alpha_lower = CT::Mask<uint8_t>::is_within_range(c, 'a', 'z');
8,996✔
30
      auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, 'A', 'Z');
8,996✔
31
      auto is_decimal = CT::Mask<uint8_t>::is_within_range(c, '0', '9');
8,996✔
32

33
      auto is_print_punc = CT::Mask<uint8_t>::is_any_of(c, {' ', '(', ')', '+', ',', '-', '.', '/', ':', '=', '?'});
8,996✔
34

35
      auto is_printable = is_alpha_lower | is_alpha_upper | is_decimal | is_print_punc;
8,996✔
36

37
      all_printable &= is_printable;
8,996✔
38
   }
39

40
   if(all_printable.is_set()) {
113,181✔
41
      return ASN1_Type::PrintableString;
42
   } else {
43
      return ASN1_Type::Utf8String;
30✔
44
   }
45
}
46

47
bool is_utf8_subset_string_type(ASN1_Type tag) {
233,236✔
48
   return (tag == ASN1_Type::NumericString || tag == ASN1_Type::PrintableString || tag == ASN1_Type::VisibleString ||
3,375✔
49
           tag == ASN1_Type::Ia5String || tag == ASN1_Type::Utf8String);
50
}
51

52
bool is_asn1_string_type(ASN1_Type tag) {
113,948✔
53
   return (is_utf8_subset_string_type(tag) || tag == ASN1_Type::TeletexString || tag == ASN1_Type::BmpString ||
113,093✔
54
           tag == ASN1_Type::UniversalString);
55
}
56

57
}  // namespace
58

59
//static
60
bool ASN1_String::is_string_type(ASN1_Type tag) { return is_asn1_string_type(tag); }
2,877✔
61

62
ASN1_String::ASN1_String(std::string_view str, ASN1_Type t) : m_utf8_str(str), m_tag(t) {
231,826✔
63
   if(!is_utf8_subset_string_type(m_tag)) {
115,913✔
64
      throw Invalid_Argument("ASN1_String only supports encoding to UTF-8 or a UTF-8 subset");
×
65
   }
66
}
115,913✔
67

68
ASN1_String::ASN1_String(std::string_view str) : ASN1_String(str, choose_encoding(str)) {}
113,181✔
69

70
/*
71
* DER encode an ASN1_String
72
*/
73
void ASN1_String::encode_into(DER_Encoder& encoder) const {
3,375✔
74
   if(m_data.empty()) {
3,375✔
75
      BOTAN_ASSERT_NOMSG(is_utf8_subset_string_type(tagging()));
3,375✔
76
      encoder.add_object(tagging(), ASN1_Class::Universal, m_utf8_str);
3,375✔
77
   } else {
78
      // If this string was decoded, reserialize using original encoding
79
      encoder.add_object(tagging(), ASN1_Class::Universal, m_data.data(), m_data.size());
×
80
   }
81
}
3,375✔
82

83
/*
84
* Decode a BER encoded ASN1_String
85
*/
86
void ASN1_String::decode_from(BER_Decoder& source) {
111,078✔
87
   BER_Object obj = source.get_next_object();
111,078✔
88

89
   if(!is_asn1_string_type(obj.type())) {
111,071✔
90
      auto typ = static_cast<uint32_t>(obj.type());
67✔
91
      throw Decoding_Error(fmt("ASN1_String: Unknown string type {}", typ));
134✔
92
   }
93

94
   m_tag = obj.type();
111,004✔
95
   m_data.assign(obj.bits(), obj.bits() + obj.length());
111,004✔
96

97
   if(m_tag == ASN1_Type::BmpString) {
111,004✔
98
      m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size());
1,175✔
99
   } else if(m_tag == ASN1_Type::UniversalString) {
109,829✔
100
      m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size());
27✔
101
   } else if(m_tag == ASN1_Type::TeletexString) {
109,802✔
102
      /*
103
      TeletexString is nominally ITU T.61 not ISO-8859-1 but it seems
104
      the majority of implementations actually used that charset here.
105
      */
106
      m_utf8_str = latin1_to_utf8(m_data.data(), m_data.size());
1,598✔
107
   } else {
108
      // All other supported string types are UTF-8 or some subset thereof
109
      m_utf8_str = ASN1::to_string(obj);
108,204✔
110
   }
111
}
110,978✔
112

113
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc