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 /********************************************************************** 194 * 195 * Tests of object creation 196 * 197 ***/ 198 199 static int test_obj_create_once(const char *oid, const char *sn, const char *ln) 200 { 201 int nid; 202 203 ERR_set_mark(); 204 205 nid = OBJ_create(oid, sn, ln); 206 207 if (nid == NID_undef) { 208 unsigned long err = ERR_peek_last_error(); 209 int l = ERR_GET_LIB(err); 210 int r = ERR_GET_REASON(err); 211 212 /* If it exists, that's fine, otherwise not */ 213 if (l != ERR_LIB_OBJ || r != OBJ_R_OID_EXISTS) { 214 ERR_clear_last_mark(); 215 return 0; 216 } 217 } 218 ERR_pop_to_mark(); 219 return 1; 220 } 221 222 static int test_obj_create(void) 223 { 224 /* Stolen from evp_extra_test.c */ 225 #define arc "1.3.6.1.4.1.16604.998866." 226 #define broken_arc "25." 227 #define sn_prefix "custom" 228 #define ln_prefix "custom" 229 230 /* Try different combinations of correct object creation */ 231 if (!TEST_true(test_obj_create_once(NULL, sn_prefix "1", NULL)) 232 || !TEST_int_ne(OBJ_sn2nid(sn_prefix "1"), NID_undef) 233 || !TEST_true(test_obj_create_once(NULL, NULL, ln_prefix "2")) 234 || !TEST_int_ne(OBJ_ln2nid(ln_prefix "2"), NID_undef) 235 || !TEST_true(test_obj_create_once(NULL, sn_prefix "3", ln_prefix "3")) 236 || !TEST_int_ne(OBJ_sn2nid(sn_prefix "3"), NID_undef) 237 || !TEST_int_ne(OBJ_ln2nid(ln_prefix "3"), NID_undef) 238 || !TEST_true(test_obj_create_once(arc "4", NULL, NULL)) 239 || !TEST_true(test_obj_create_once(arc "5", sn_prefix "5", NULL)) 240 || !TEST_int_ne(OBJ_sn2nid(sn_prefix "5"), NID_undef) 241 || !TEST_true(test_obj_create_once(arc "6", NULL, ln_prefix "6")) 242 || !TEST_int_ne(OBJ_ln2nid(ln_prefix "6"), NID_undef) 243 || !TEST_true(test_obj_create_once(arc "7", 244 sn_prefix "7", ln_prefix "7")) 245 || !TEST_int_ne(OBJ_sn2nid(sn_prefix "7"), NID_undef) 246 || !TEST_int_ne(OBJ_ln2nid(ln_prefix "7"), NID_undef)) 247 return 0; 248 249 if (!TEST_false(test_obj_create_once(NULL, NULL, NULL)) 250 || !TEST_false(test_obj_create_once(broken_arc "8", 251 sn_prefix "8", ln_prefix "8"))) 252 return 0; 253 254 return 1; 255 } 256 257 static int test_obj_nid_undef(void) 258 { 259 if (!TEST_ptr(OBJ_nid2obj(NID_undef)) 260 || !TEST_ptr(OBJ_nid2sn(NID_undef)) 261 || !TEST_ptr(OBJ_nid2ln(NID_undef))) 262 return 0; 263 264 return 1; 265 } 266 267 int setup_tests(void) 268 { 269 ADD_TEST(test_tbl_standard); 270 ADD_TEST(test_standard_methods); 271 ADD_TEST(test_empty_nonoptional_content); 272 ADD_TEST(test_unicode_range); 273 ADD_TEST(test_obj_create); 274 ADD_TEST(test_obj_nid_undef); 275 return 1; 276 } 277