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