1 /* 2 * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <string.h> 12 13 #include <openssl/rand.h> 14 #include <openssl/asn1t.h> 15 #include <openssl/obj_mac.h> 16 #include "internal/numbers.h" 17 #include "testutil.h" 18 19 #ifdef __GNUC__ 20 # pragma GCC diagnostic ignored "-Wunused-function" 21 #endif 22 #ifdef __clang__ 23 # pragma clang diagnostic ignored "-Wunused-function" 24 #endif 25 26 /* Badly coded ASN.1 INTEGER zero wrapped in a sequence */ 27 static unsigned char t_invalid_zero[] = { 28 0x30, 0x02, /* SEQUENCE tag + length */ 29 0x02, 0x00 /* INTEGER tag + length */ 30 }; 31 32 #ifndef OPENSSL_NO_DEPRECATED_3_0 33 /* LONG case ************************************************************* */ 34 35 typedef struct { 36 long test_long; 37 } ASN1_LONG_DATA; 38 39 ASN1_SEQUENCE(ASN1_LONG_DATA) = { 40 ASN1_EMBED(ASN1_LONG_DATA, test_long, LONG), 41 } static_ASN1_SEQUENCE_END(ASN1_LONG_DATA) 42 43 IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_LONG_DATA) 44 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_LONG_DATA) 45 46 static int test_long(void) 47 { 48 const unsigned char *p = t_invalid_zero; 49 ASN1_LONG_DATA *dectst = 50 d2i_ASN1_LONG_DATA(NULL, &p, sizeof(t_invalid_zero)); 51 52 if (dectst == NULL) 53 return 0; /* Fail */ 54 55 ASN1_LONG_DATA_free(dectst); 56 return 1; 57 } 58 #endif 59 60 /* INT32 case ************************************************************* */ 61 62 typedef struct { 63 int32_t test_int32; 64 } ASN1_INT32_DATA; 65 66 ASN1_SEQUENCE(ASN1_INT32_DATA) = { 67 ASN1_EMBED(ASN1_INT32_DATA, test_int32, INT32), 68 } static_ASN1_SEQUENCE_END(ASN1_INT32_DATA) 69 70 IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA) 71 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT32_DATA) 72 73 static int test_int32(void) 74 { 75 const unsigned char *p = t_invalid_zero; 76 ASN1_INT32_DATA *dectst = 77 d2i_ASN1_INT32_DATA(NULL, &p, sizeof(t_invalid_zero)); 78 79 if (dectst == NULL) 80 return 0; /* Fail */ 81 82 ASN1_INT32_DATA_free(dectst); 83 return 1; 84 } 85 86 /* UINT32 case ************************************************************* */ 87 88 typedef struct { 89 uint32_t test_uint32; 90 } ASN1_UINT32_DATA; 91 92 ASN1_SEQUENCE(ASN1_UINT32_DATA) = { 93 ASN1_EMBED(ASN1_UINT32_DATA, test_uint32, UINT32), 94 } static_ASN1_SEQUENCE_END(ASN1_UINT32_DATA) 95 96 IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA) 97 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT32_DATA) 98 99 static int test_uint32(void) 100 { 101 const unsigned char *p = t_invalid_zero; 102 ASN1_UINT32_DATA *dectst = 103 d2i_ASN1_UINT32_DATA(NULL, &p, sizeof(t_invalid_zero)); 104 105 if (dectst == NULL) 106 return 0; /* Fail */ 107 108 ASN1_UINT32_DATA_free(dectst); 109 return 1; 110 } 111 112 /* INT64 case ************************************************************* */ 113 114 typedef struct { 115 int64_t test_int64; 116 } ASN1_INT64_DATA; 117 118 ASN1_SEQUENCE(ASN1_INT64_DATA) = { 119 ASN1_EMBED(ASN1_INT64_DATA, test_int64, INT64), 120 } static_ASN1_SEQUENCE_END(ASN1_INT64_DATA) 121 122 IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA) 123 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT64_DATA) 124 125 static int test_int64(void) 126 { 127 const unsigned char *p = t_invalid_zero; 128 ASN1_INT64_DATA *dectst = 129 d2i_ASN1_INT64_DATA(NULL, &p, sizeof(t_invalid_zero)); 130 131 if (dectst == NULL) 132 return 0; /* Fail */ 133 134 ASN1_INT64_DATA_free(dectst); 135 return 1; 136 } 137 138 /* UINT64 case ************************************************************* */ 139 140 typedef struct { 141 uint64_t test_uint64; 142 } ASN1_UINT64_DATA; 143 144 ASN1_SEQUENCE(ASN1_UINT64_DATA) = { 145 ASN1_EMBED(ASN1_UINT64_DATA, test_uint64, UINT64), 146 } static_ASN1_SEQUENCE_END(ASN1_UINT64_DATA) 147 148 IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA) 149 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT64_DATA) 150 151 static int test_uint64(void) 152 { 153 const unsigned char *p = t_invalid_zero; 154 ASN1_UINT64_DATA *dectst = 155 d2i_ASN1_UINT64_DATA(NULL, &p, sizeof(t_invalid_zero)); 156 157 if (dectst == NULL) 158 return 0; /* Fail */ 159 160 ASN1_UINT64_DATA_free(dectst); 161 return 1; 162 } 163 164 typedef struct { 165 ASN1_STRING *invalidDirString; 166 } INVALIDTEMPLATE; 167 168 ASN1_SEQUENCE(INVALIDTEMPLATE) = { 169 /* 170 * DirectoryString is a CHOICE type so it must use explicit tagging - 171 * but we deliberately use implicit here, which makes this template invalid. 172 */ 173 ASN1_IMP(INVALIDTEMPLATE, invalidDirString, DIRECTORYSTRING, 12) 174 } static_ASN1_SEQUENCE_END(INVALIDTEMPLATE) 175 176 IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE) 177 IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(INVALIDTEMPLATE) 178 179 /* Empty sequence for invalid template test */ 180 static unsigned char t_invalid_template[] = { 181 0x30, 0x03, /* SEQUENCE tag + length */ 182 0x0c, 0x01, 0x41 /* UTF8String, length 1, "A" */ 183 }; 184 185 static int test_invalid_template(void) 186 { 187 const unsigned char *p = t_invalid_template; 188 INVALIDTEMPLATE *tmp = d2i_INVALIDTEMPLATE(NULL, &p, 189 sizeof(t_invalid_template)); 190 191 /* We expect a NULL pointer return */ 192 if (TEST_ptr_null(tmp)) 193 return 1; 194 195 INVALIDTEMPLATE_free(tmp); 196 return 0; 197 } 198 199 static int test_reuse_asn1_object(void) 200 { 201 static unsigned char cn_der[] = { 0x06, 0x03, 0x55, 0x04, 0x06 }; 202 static unsigned char oid_der[] = { 203 0x06, 0x06, 0x2a, 0x03, 0x04, 0x05, 0x06, 0x07 204 }; 205 int ret = 0; 206 ASN1_OBJECT *obj; 207 unsigned char const *p = oid_der; 208 209 /* Create an object that owns dynamically allocated 'sn' and 'ln' fields */ 210 211 if (!TEST_ptr(obj = ASN1_OBJECT_create(NID_undef, cn_der, sizeof(cn_der), 212 "C", "countryName"))) 213 goto err; 214 /* reuse obj - this should not leak sn and ln */ 215 if (!TEST_ptr(d2i_ASN1_OBJECT(&obj, &p, sizeof(oid_der)))) 216 goto err; 217 ret = 1; 218 err: 219 ASN1_OBJECT_free(obj); 220 return ret; 221 } 222 223 int setup_tests(void) 224 { 225 #ifndef OPENSSL_NO_DEPRECATED_3_0 226 ADD_TEST(test_long); 227 #endif 228 ADD_TEST(test_int32); 229 ADD_TEST(test_uint32); 230 ADD_TEST(test_int64); 231 ADD_TEST(test_uint64); 232 ADD_TEST(test_invalid_template); 233 ADD_TEST(test_reuse_asn1_object); 234 return 1; 235 } 236