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 */ 27static 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 35typedef struct { 36 long test_long; 37} ASN1_LONG_DATA; 38 39ASN1_SEQUENCE(ASN1_LONG_DATA) = { 40 ASN1_EMBED(ASN1_LONG_DATA, test_long, LONG), 41} static_ASN1_SEQUENCE_END(ASN1_LONG_DATA) 42 43IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_LONG_DATA) 44IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_LONG_DATA) 45 46static 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 62typedef struct { 63 int32_t test_int32; 64} ASN1_INT32_DATA; 65 66ASN1_SEQUENCE(ASN1_INT32_DATA) = { 67 ASN1_EMBED(ASN1_INT32_DATA, test_int32, INT32), 68} static_ASN1_SEQUENCE_END(ASN1_INT32_DATA) 69 70IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT32_DATA) 71IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT32_DATA) 72 73static 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 88typedef struct { 89 uint32_t test_uint32; 90} ASN1_UINT32_DATA; 91 92ASN1_SEQUENCE(ASN1_UINT32_DATA) = { 93 ASN1_EMBED(ASN1_UINT32_DATA, test_uint32, UINT32), 94} static_ASN1_SEQUENCE_END(ASN1_UINT32_DATA) 95 96IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT32_DATA) 97IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT32_DATA) 98 99static 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 114typedef struct { 115 int64_t test_int64; 116} ASN1_INT64_DATA; 117 118ASN1_SEQUENCE(ASN1_INT64_DATA) = { 119 ASN1_EMBED(ASN1_INT64_DATA, test_int64, INT64), 120} static_ASN1_SEQUENCE_END(ASN1_INT64_DATA) 121 122IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_INT64_DATA) 123IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_INT64_DATA) 124 125static 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 140typedef struct { 141 uint64_t test_uint64; 142} ASN1_UINT64_DATA; 143 144ASN1_SEQUENCE(ASN1_UINT64_DATA) = { 145 ASN1_EMBED(ASN1_UINT64_DATA, test_uint64, UINT64), 146} static_ASN1_SEQUENCE_END(ASN1_UINT64_DATA) 147 148IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(ASN1_UINT64_DATA) 149IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_UINT64_DATA) 150 151static 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 164typedef struct { 165 ASN1_STRING *invalidDirString; 166} INVALIDTEMPLATE; 167 168ASN1_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 176IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(INVALIDTEMPLATE) 177IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(INVALIDTEMPLATE) 178 179/* Empty sequence for invalid template test */ 180static unsigned char t_invalid_template[] = { 181 0x30, 0x03, /* SEQUENCE tag + length */ 182 0x0c, 0x01, 0x41 /* UTF8String, length 1, "A" */ 183}; 184 185static 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 199static 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; 218err: 219 ASN1_OBJECT_free(obj); 220 return ret; 221} 222 223int 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