1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 *
4 * LibTomCrypt is a library that provides various cryptographic
5 * algorithms in a highly modular and flexible manner.
6 *
7 * The library is free for all purposes without any express
8 * guarantee it works.
9 */
10 #include "tomcrypt_private.h"
11
12 /**
13 @file der_length_utf8_string.c
14 ASN.1 DER, get length of UTF8 STRING, Tom St Denis
15 */
16
17 #ifdef LTC_DER
18
19 /** Return the size in bytes of a UTF-8 character
20 @param c The UTF-8 character to measure
21 @return The size in bytes
22 */
der_utf8_charsize(const wchar_t c)23 unsigned long der_utf8_charsize(const wchar_t c)
24 {
25 if (c <= 0x7F) {
26 return 1;
27 }
28 if (c <= 0x7FF) {
29 return 2;
30 }
31 #if LTC_WCHAR_MAX == 0xFFFF
32 return 3;
33 #else
34 if (c <= 0xFFFF) {
35 return 3;
36 }
37 return 4;
38 #endif
39 }
40
41 /**
42 Test whether the given code point is valid character
43 @param c The UTF-8 character to test
44 @return 1 - valid, 0 - invalid
45 */
der_utf8_valid_char(const wchar_t c)46 int der_utf8_valid_char(const wchar_t c)
47 {
48 LTC_UNUSED_PARAM(c);
49 #if !defined(LTC_WCHAR_MAX) || LTC_WCHAR_MAX > 0xFFFF
50 if (c > 0x10FFFF) return 0;
51 #endif
52 #if LTC_WCHAR_MAX != 0xFFFF && LTC_WCHAR_MAX != 0xFFFFFFFF
53 if (c < 0) return 0;
54 #endif
55 return 1;
56 }
57
58 /**
59 Gets length of DER encoding of UTF8 STRING
60 @param in The characters to measure the length of
61 @param noctets The number of octets in the string to encode
62 @param outlen [out] The length of the DER encoding for the given string
63 @return CRYPT_OK if successful
64 */
der_length_utf8_string(const wchar_t * in,unsigned long noctets,unsigned long * outlen)65 int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen)
66 {
67 unsigned long x, len;
68 int err;
69
70 LTC_ARGCHK(in != NULL);
71 LTC_ARGCHK(outlen != NULL);
72
73 len = 0;
74 for (x = 0; x < noctets; x++) {
75 if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG;
76 len += der_utf8_charsize(in[x]);
77 }
78
79 if ((err = der_length_asn1_length(len, &x)) != CRYPT_OK) {
80 return err;
81 }
82 *outlen = 1 + x + len;
83
84 return CRYPT_OK;
85 }
86
87 #endif
88
89
90 /* ref: $Format:%D$ */
91 /* git commit: $Format:%H$ */
92 /* commit time: $Format:%ai$ */
93