1 /* 2 * Copyright 1999-2023 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 /* Internal tests for the asn1 module */ 11 12 /* 13 * RSA low level APIs are deprecated for public use, but still ok for 14 * internal use. 15 */ 16 #include "internal/deprecated.h" 17 18 #include <stdio.h> 19 #include <string.h> 20 21 #include <openssl/asn1.h> 22 #include <openssl/evp.h> 23 #include <openssl/objects.h> 24 #include "testutil.h" 25 #include "internal/nelem.h" 26 27 /********************************************************************** 28 * 29 * Test of a_strnid's tbl_standard 30 * 31 ***/ 32 33 #include "../crypto/asn1/tbl_standard.h" 34 35 static int test_tbl_standard(void) 36 { 37 const ASN1_STRING_TABLE *tmp; 38 int last_nid = -1; 39 size_t i; 40 41 for (tmp = tbl_standard, i = 0; i < OSSL_NELEM(tbl_standard); i++, tmp++) { 42 if (tmp->nid < last_nid) { 43 last_nid = 0; 44 break; 45 } 46 last_nid = tmp->nid; 47 } 48 49 if (TEST_int_ne(last_nid, 0)) { 50 TEST_info("asn1 tbl_standard: Table order OK"); 51 return 1; 52 } 53 54 TEST_info("asn1 tbl_standard: out of order"); 55 for (tmp = tbl_standard, i = 0; i < OSSL_NELEM(tbl_standard); i++, tmp++) 56 TEST_note("asn1 tbl_standard: Index %zu, NID %d, Name=%s", 57 i, tmp->nid, OBJ_nid2ln(tmp->nid)); 58 59 return 0; 60 } 61 62 /********************************************************************** 63 * 64 * Test of ameth_lib's standard_methods 65 * 66 ***/ 67 68 #include "crypto/asn1.h" 69 #include "../crypto/asn1/standard_methods.h" 70 71 static int test_standard_methods(void) 72 { 73 const EVP_PKEY_ASN1_METHOD **tmp; 74 int last_pkey_id = -1; 75 size_t i; 76 int ok = 1; 77 78 for (tmp = standard_methods, i = 0; i < OSSL_NELEM(standard_methods); 79 i++, tmp++) { 80 if ((*tmp)->pkey_id < last_pkey_id) { 81 last_pkey_id = 0; 82 break; 83 } 84 last_pkey_id = (*tmp)->pkey_id; 85 86 /* 87 * One of the following must be true: 88 * 89 * pem_str == NULL AND ASN1_PKEY_ALIAS is set 90 * pem_str != NULL AND ASN1_PKEY_ALIAS is clear 91 * 92 * Anything else is an error and may lead to a corrupt ASN1 method table 93 */ 94 if (!TEST_true(((*tmp)->pem_str == NULL && ((*tmp)->pkey_flags & ASN1_PKEY_ALIAS) != 0) 95 || ((*tmp)->pem_str != NULL && ((*tmp)->pkey_flags & ASN1_PKEY_ALIAS) == 0))) { 96 TEST_note("asn1 standard methods: Index %zu, pkey ID %d, Name=%s", 97 i, (*tmp)->pkey_id, OBJ_nid2sn((*tmp)->pkey_id)); 98 ok = 0; 99 } 100 } 101 102 if (TEST_int_ne(last_pkey_id, 0)) { 103 TEST_info("asn1 standard methods: Table order OK"); 104 return ok; 105 } 106 107 TEST_note("asn1 standard methods: out of order"); 108 for (tmp = standard_methods, i = 0; i < OSSL_NELEM(standard_methods); 109 i++, tmp++) 110 TEST_note("asn1 standard methods: Index %zu, pkey ID %d, Name=%s", 111 i, (*tmp)->pkey_id, OBJ_nid2sn((*tmp)->pkey_id)); 112 113 return 0; 114 } 115 116 /********************************************************************** 117 * 118 * Test of that i2d fail on non-existing non-optional items 119 * 120 ***/ 121 122 #include <openssl/rsa.h> 123 124 static int test_empty_nonoptional_content(void) 125 { 126 RSA *rsa = NULL; 127 BIGNUM *n = NULL; 128 BIGNUM *e = NULL; 129 int ok = 0; 130 131 if (!TEST_ptr(rsa = RSA_new()) 132 || !TEST_ptr(n = BN_new()) 133 || !TEST_ptr(e = BN_new()) 134 || !TEST_true(RSA_set0_key(rsa, n, e, NULL))) 135 goto end; 136 137 n = e = NULL; /* They are now "owned" by |rsa| */ 138 139 /* 140 * This SHOULD fail, as we're trying to encode a public key as a private 141 * key. The private key bits MUST be present for a proper RSAPrivateKey. 142 */ 143 if (TEST_int_le(i2d_RSAPrivateKey(rsa, NULL), 0)) 144 ok = 1; 145 146 end: 147 RSA_free(rsa); 148 BN_free(n); 149 BN_free(e); 150 return ok; 151 } 152 153 /********************************************************************** 154 * 155 * Tests of the Unicode code point range 156 * 157 ***/ 158 159 static int test_unicode(const unsigned char *univ, size_t len, int expected) 160 { 161 const unsigned char *end = univ + len; 162 int ok = 1; 163 164 for (; univ < end; univ += 4) { 165 if (!TEST_int_eq(ASN1_mbstring_copy(NULL, univ, 4, MBSTRING_UNIV, 166 B_ASN1_UTF8STRING), 167 expected)) 168 ok = 0; 169 } 170 return ok; 171 } 172 173 static int test_unicode_range(void) 174 { 175 const unsigned char univ_ok[] = "\0\0\0\0" 176 "\0\0\xd7\xff" 177 "\0\0\xe0\x00" 178 "\0\x10\xff\xff"; 179 const unsigned char univ_bad[] = "\0\0\xd8\x00" 180 "\0\0\xdf\xff" 181 "\0\x11\x00\x00" 182 "\x80\x00\x00\x00" 183 "\xff\xff\xff\xff"; 184 int ok = 1; 185 186 if (!test_unicode(univ_ok, sizeof univ_ok - 1, V_ASN1_UTF8STRING)) 187 ok = 0; 188 if (!test_unicode(univ_bad, sizeof univ_bad - 1, -1)) 189 ok = 0; 190 return ok; 191 } 192 193 static int test_invalid_utf8(void) 194 { 195 const unsigned char inv_utf8[] = "\xF4\x90\x80\x80"; 196 unsigned long val; 197 198 if (!TEST_int_lt(UTF8_getc(inv_utf8, sizeof(inv_utf8), &val), 0)) 199 return 0; 200 return 1; 201 } 202 203 /********************************************************************** 204 * 205 * Tests of object creation 206 * 207 ***/ 208 209 static int test_obj_create_once(const char *oid, const char *sn, const char *ln) 210 { 211 int nid; 212 213 ERR_set_mark(); 214 215 nid = OBJ_create(oid, sn, ln); 216 217 if (nid == NID_undef) { 218 unsigned long err = ERR_peek_last_error(); 219 int l = ERR_GET_LIB(err); 220 int r = ERR_GET_REASON(err); 221 222 /* If it exists, that's fine, otherwise not */ 223 if (l != ERR_LIB_OBJ || r != OBJ_R_OID_EXISTS) { 224 ERR_clear_last_mark(); 225 return 0; 226 } 227 } 228 ERR_pop_to_mark(); 229 return 1; 230 } 231 232 static int test_obj_create(void) 233 { 234 /* Stolen from evp_extra_test.c */ 235 #define arc "1.3.6.1.4.1.16604.998866." 236 #define broken_arc "25." 237 #define sn_prefix "custom" 238 #define ln_prefix "custom" 239 240 /* Try different combinations of correct object creation */ 241 if (!TEST_true(test_obj_create_once(NULL, sn_prefix "1", NULL)) 242 || !TEST_int_ne(OBJ_sn2nid(sn_prefix "1"), NID_undef) 243 || !TEST_true(test_obj_create_once(NULL, NULL, ln_prefix "2")) 244 || !TEST_int_ne(OBJ_ln2nid(ln_prefix "2"), NID_undef) 245 || !TEST_true(test_obj_create_once(NULL, sn_prefix "3", ln_prefix "3")) 246 || !TEST_int_ne(OBJ_sn2nid(sn_prefix "3"), NID_undef) 247 || !TEST_int_ne(OBJ_ln2nid(ln_prefix "3"), NID_undef) 248 || !TEST_true(test_obj_create_once(arc "4", NULL, NULL)) 249 || !TEST_true(test_obj_create_once(arc "5", sn_prefix "5", NULL)) 250 || !TEST_int_ne(OBJ_sn2nid(sn_prefix "5"), NID_undef) 251 || !TEST_true(test_obj_create_once(arc "6", NULL, ln_prefix "6")) 252 || !TEST_int_ne(OBJ_ln2nid(ln_prefix "6"), NID_undef) 253 || !TEST_true(test_obj_create_once(arc "7", 254 sn_prefix "7", ln_prefix "7")) 255 || !TEST_int_ne(OBJ_sn2nid(sn_prefix "7"), NID_undef) 256 || !TEST_int_ne(OBJ_ln2nid(ln_prefix "7"), NID_undef)) 257 return 0; 258 259 if (!TEST_false(test_obj_create_once(NULL, NULL, NULL)) 260 || !TEST_false(test_obj_create_once(broken_arc "8", 261 sn_prefix "8", ln_prefix "8"))) 262 return 0; 263 264 return 1; 265 } 266 267 static int test_obj_nid_undef(void) 268 { 269 if (!TEST_ptr(OBJ_nid2obj(NID_undef)) 270 || !TEST_ptr(OBJ_nid2sn(NID_undef)) 271 || !TEST_ptr(OBJ_nid2ln(NID_undef))) 272 return 0; 273 274 return 1; 275 } 276 277 static int test_mbstring_ncopy(void) 278 { 279 ASN1_STRING *str = NULL; 280 const unsigned char in[] = { 0xFF, 0xFE, 0xFF, 0xFE }; 281 int inlen = 4; 282 int inform = MBSTRING_UNIV; 283 284 if (!TEST_int_eq(ASN1_mbstring_ncopy(&str, in, inlen, inform, B_ASN1_GENERALSTRING, 0, 0), -1) 285 || !TEST_int_eq(ASN1_mbstring_ncopy(&str, in, inlen, inform, B_ASN1_VISIBLESTRING, 0, 0), -1) 286 || !TEST_int_eq(ASN1_mbstring_ncopy(&str, in, inlen, inform, B_ASN1_VIDEOTEXSTRING, 0, 0), -1) 287 || !TEST_int_eq(ASN1_mbstring_ncopy(&str, in, inlen, inform, B_ASN1_GENERALIZEDTIME, 0, 0), -1)) 288 return 0; 289 290 return 1; 291 } 292 293 int setup_tests(void) 294 { 295 ADD_TEST(test_tbl_standard); 296 ADD_TEST(test_standard_methods); 297 ADD_TEST(test_empty_nonoptional_content); 298 ADD_TEST(test_unicode_range); 299 ADD_TEST(test_invalid_utf8); 300 ADD_TEST(test_obj_create); 301 ADD_TEST(test_obj_nid_undef); 302 ADD_TEST(test_mbstring_ncopy); 303 return 1; 304 } 305