Botan 2.19.0
Crypto and TLS for C&
asn1_str.cpp
Go to the documentation of this file.
1/*
2* Simple ASN.1 String Types
3* (C) 1999-2007 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/asn1_obj.h>
9#include <botan/der_enc.h>
10#include <botan/ber_dec.h>
11#include <botan/charset.h>
12
13namespace Botan {
14
15namespace {
16
17/*
18* Choose an encoding for the string
19*/
20ASN1_Tag choose_encoding(const std::string& str)
21 {
22 static const uint8_t IS_PRINTABLE[256] = {
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
26 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
27 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
28 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
29 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
30 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
32 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
33 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00 };
45
46 for(size_t i = 0; i != str.size(); ++i)
47 {
48 if(!IS_PRINTABLE[static_cast<uint8_t>(str[i])])
49 {
50 return UTF8_STRING;
51 }
52 }
53 return PRINTABLE_STRING;
54 }
55
56void assert_is_string_type(ASN1_Tag tag)
57 {
59 {
60 throw Invalid_Argument("ASN1_String: Unknown string type " +
61 std::to_string(tag));
62 }
63 }
64
65}
66
67//static
69 {
70 return (tag == NUMERIC_STRING ||
71 tag == PRINTABLE_STRING ||
72 tag == VISIBLE_STRING ||
73 tag == T61_STRING ||
74 tag == IA5_STRING ||
75 tag == UTF8_STRING ||
76 tag == BMP_STRING ||
77 tag == UNIVERSAL_STRING);
78 }
79
80
81/*
82* Create an ASN1_String
83*/
84ASN1_String::ASN1_String(const std::string& str, ASN1_Tag t) : m_utf8_str(str), m_tag(t)
85 {
86 if(m_tag == DIRECTORY_STRING)
87 {
88 m_tag = choose_encoding(m_utf8_str);
89 }
90
91 assert_is_string_type(m_tag);
92 }
93
94/*
95* Create an ASN1_String
96*/
97ASN1_String::ASN1_String(const std::string& str) :
98 m_utf8_str(str),
99 m_tag(choose_encoding(m_utf8_str))
100 {}
101
102/*
103* Return this string in ISO 8859-1 encoding
104*/
105std::string ASN1_String::iso_8859() const
106 {
107 return utf8_to_latin1(m_utf8_str);
108 }
109
110/*
111* DER encode an ASN1_String
112*/
114 {
115 if(m_data.empty())
116 {
117 encoder.add_object(tagging(), UNIVERSAL, m_utf8_str);
118 }
119 else
120 {
121 // If this string was decoded, reserialize using original encoding
122 encoder.add_object(tagging(), UNIVERSAL, m_data.data(), m_data.size());
123 }
124 }
125
126/*
127* Decode a BER encoded ASN1_String
128*/
130 {
131 BER_Object obj = source.get_next_object();
132
133 assert_is_string_type(obj.type());
134
135 m_tag = obj.type();
136 m_data.assign(obj.bits(), obj.bits() + obj.length());
137
138 if(m_tag == BMP_STRING)
139 {
140 m_utf8_str = ucs2_to_utf8(m_data.data(), m_data.size());
141 }
142 else if(m_tag == UNIVERSAL_STRING)
143 {
144 m_utf8_str = ucs4_to_utf8(m_data.data(), m_data.size());
145 }
146 else
147 {
148 // All other supported string types are UTF-8 or some subset thereof
149 m_utf8_str = ASN1::to_string(obj);
150 }
151 }
152
153}
static bool is_string_type(ASN1_Tag tag)
Definition: asn1_str.cpp:68
std::string iso_8859() const
Definition: asn1_str.cpp:105
ASN1_String(const std::string &utf8="")
Definition: asn1_str.cpp:97
void decode_from(class BER_Decoder &) override
Definition: asn1_str.cpp:129
void encode_into(class DER_Encoder &) const override
Definition: asn1_str.cpp:113
ASN1_Tag tagging() const
Definition: asn1_obj.h:398
BER_Object get_next_object()
Definition: ber_dec.cpp:237
size_t length() const
Definition: asn1_obj.h:121
ASN1_Tag type() const
Definition: asn1_obj.h:116
const uint8_t * bits() const
Definition: asn1_obj.h:119
DER_Encoder & add_object(ASN1_Tag type_tag, ASN1_Tag class_tag, const uint8_t rep[], size_t length)
Definition: der_enc.cpp:249
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
Definition: alg_id.cpp:13
std::string ucs4_to_utf8(const uint8_t ucs4[], size_t len)
Definition: charset.cpp:78
std::string ucs2_to_utf8(const uint8_t ucs2[], size_t len)
Definition: charset.cpp:61
std::string utf8_to_latin1(const std::string &utf8)
Definition: charset.cpp:98
ASN1_Tag
Definition: asn1_obj.h:25
@ DIRECTORY_STRING
Definition: asn1_obj.h:59
@ IA5_STRING
Definition: asn1_obj.h:49
@ UNIVERSAL_STRING
Definition: asn1_obj.h:51
@ PRINTABLE_STRING
Definition: asn1_obj.h:47
@ T61_STRING
Definition: asn1_obj.h:48
@ UTF8_STRING
Definition: asn1_obj.h:45
@ NUMERIC_STRING
Definition: asn1_obj.h:46
@ BMP_STRING
Definition: asn1_obj.h:52
@ UNIVERSAL
Definition: asn1_obj.h:26
@ VISIBLE_STRING
Definition: asn1_obj.h:50