Browse Source

add pkcs12_utf8_to_utf16()

Karel Miko 7 years ago
parent
commit
a96997dd29
2 changed files with 63 additions and 0 deletions
  1. 3 0
      src/headers/tomcrypt_private.h
  2. 60 0
      src/misc/pkcs12/pkcs12_utf8_to_utf16.c

+ 3 - 0
src/headers/tomcrypt_private.h

@@ -309,6 +309,9 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i
 
 #ifdef LTC_PKCS_12
 
+int pkcs12_utf8_to_utf16(const unsigned char *in,  unsigned long  inlen,
+                               unsigned char *out, unsigned long *outlen);
+
 int pkcs12_kdf(               int   hash_id,
                const unsigned char *pw,         unsigned long pwlen,
                const unsigned char *salt,       unsigned long saltlen,

+ 60 - 0
src/misc/pkcs12/pkcs12_utf8_to_utf16.c

@@ -0,0 +1,60 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+#include "tomcrypt_private.h"
+
+#ifdef LTC_PKCS_12
+
+int pkcs12_utf8_to_utf16(const unsigned char *in,  unsigned long  inlen,
+                               unsigned char *out, unsigned long *outlen) {
+   unsigned long len = 0;
+   const unsigned char* in_end = in + inlen;
+   const ulong32 offset[6] = {
+      0x00000000UL, 0x00003080UL, 0x000E2080UL,
+      0x03C82080UL, 0xFA082080UL, 0x82082080UL
+   };
+   int err = CRYPT_ERROR;
+
+   while (in < in_end) {
+      ulong32 ch = 0;
+      unsigned short extra = 0; /* 0 */
+      if (*in >= 192) extra++;  /* 1 */
+      if (*in >= 224) extra++;  /* 2 */
+      if (*in >= 240) extra++;  /* 3 */
+      if (*in >= 248) extra++;  /* 4 */
+      if (*in >= 252) extra++;  /* 5 */
+      if (in + extra >= in_end) goto ERROR;
+      switch (extra) {
+         case 5: ch += *in++; ch <<= 6;
+         case 4: ch += *in++; ch <<= 6;
+         case 3: ch += *in++; ch <<= 6;
+         case 2: ch += *in++; ch <<= 6;
+         case 1: ch += *in++; ch <<= 6;
+         case 0: ch += *in++;
+      }
+      ch -= offset[extra];
+      if (ch > 0xFFFF) goto ERROR;
+      if (*outlen >= len + 2) {
+         out[len] = (unsigned short)((ch >> 8) & 0xFF);
+         out[len + 1] = (unsigned char)(ch & 0xFF);
+      }
+      len += 2;
+   }
+
+   err = len > *outlen ? CRYPT_BUFFER_OVERFLOW : CRYPT_OK;
+   *outlen = len;
+ERROR:
+   return err;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */