summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormiod <>2016-11-05 14:24:29 +0000
committermiod <>2016-11-05 14:24:29 +0000
commitac13059ace7b9575014c51d74e96157cc83bfca9 (patch)
treeff45b5f6130e7cdb925a21e950f4b1d353763270
parent71b431bd059aaefaa67b54a34adfaadc4014902c (diff)
downloadopenbsd-ac13059ace7b9575014c51d74e96157cc83bfca9.tar.gz
openbsd-ac13059ace7b9575014c51d74e96157cc83bfca9.tar.bz2
openbsd-ac13059ace7b9575014c51d74e96157cc83bfca9.zip
Stricter validation of inputs of OPENSSL_asc2uni() and OPENSSL_uni2asc().
While there, try to make these slightly less obfuscated. ok beck@ jsing@
-rw-r--r--src/lib/libcrypto/pkcs12/p12_utl.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_utl.c b/src/lib/libcrypto/pkcs12/p12_utl.c
index b60d4d020c..d7b9f9d2e6 100644
--- a/src/lib/libcrypto/pkcs12/p12_utl.c
+++ b/src/lib/libcrypto/pkcs12/p12_utl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: p12_utl.c,v 1.12 2014/07/11 08:44:49 jsing Exp $ */ 1/* $OpenBSD: p12_utl.c,v 1.13 2016/11/05 14:24:29 miod Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999. 3 * project 1999.
4 */ 4 */
@@ -56,6 +56,7 @@
56 * 56 *
57 */ 57 */
58 58
59#include <limits.h>
59#include <stdio.h> 60#include <stdio.h>
60#include <string.h> 61#include <string.h>
61 62
@@ -66,19 +67,29 @@
66unsigned char * 67unsigned char *
67OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen) 68OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen)
68{ 69{
69 int ulen, i; 70 size_t ulen, i;
70 unsigned char *unitmp; 71 unsigned char *unitmp;
71 72
72 if (asclen == -1) 73 if (asclen < 0)
73 asclen = strlen(asc); 74 ulen = strlen(asc);
74 ulen = asclen * 2 + 2; 75 else
75 if (!(unitmp = malloc(ulen))) 76 ulen = (size_t)asclen;
77 ulen++;
78 if (ulen == 0) /* unlikely overflow */
76 return NULL; 79 return NULL;
80 if ((unitmp = reallocarray(NULL, ulen, 2)) == NULL)
81 return NULL;
82 ulen *= 2;
83 /* XXX This interface ought to use unsigned types */
84 if (ulen > INT_MAX) {
85 free(unitmp);
86 return NULL;
87 }
77 for (i = 0; i < ulen - 2; i += 2) { 88 for (i = 0; i < ulen - 2; i += 2) {
78 unitmp[i] = 0; 89 unitmp[i] = 0;
79 unitmp[i + 1] = asc[i >> 1]; 90 unitmp[i + 1] = *asc++;
80 } 91 }
81 /* Make result double null terminated */ 92 /* Make result double-NUL terminated */
82 unitmp[ulen - 2] = 0; 93 unitmp[ulen - 2] = 0;
83 unitmp[ulen - 1] = 0; 94 unitmp[ulen - 1] = 0;
84 if (unilen) 95 if (unilen)
@@ -91,19 +102,25 @@ OPENSSL_asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen)
91char * 102char *
92OPENSSL_uni2asc(unsigned char *uni, int unilen) 103OPENSSL_uni2asc(unsigned char *uni, int unilen)
93{ 104{
94 int asclen, i; 105 size_t asclen, u16len, i;
95 char *asctmp; 106 char *asctmp;
96 107
97 asclen = unilen / 2; 108 if (unilen < 0)
98 /* If no terminating zero allow for one */ 109 return NULL;
99 if (!unilen || uni[unilen - 1]) 110
111 asclen = u16len = (size_t)unilen / 2;
112 /* If no terminating NUL, allow for one */
113 if (unilen == 0 || uni[unilen - 1] != '\0')
100 asclen++; 114 asclen++;
101 uni++; 115 if ((asctmp = malloc(asclen)) == NULL)
102 if (!(asctmp = malloc(asclen)))
103 return NULL; 116 return NULL;
104 for (i = 0; i < unilen; i += 2) 117 /* Skip first zero byte */
105 asctmp[i >> 1] = uni[i]; 118 uni++;
106 asctmp[asclen - 1] = 0; 119 for (i = 0; i < u16len; i++) {
120 asctmp[i] = *uni;
121 uni += 2;
122 }
123 asctmp[asclen - 1] = '\0';
107 return asctmp; 124 return asctmp;
108} 125}
109 126