1 /* Copyright (c) 2016, Google Inc. 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15 #include <stdio.h> 16 #include <string.h> 17 18 #include <openssl/asn1.h> 19 #include <openssl/bytestring.h> 20 #include <openssl/crypto.h> 21 #include <openssl/obj.h> 22 23 #include "../internal.h" 24 25 26 static bool TestBasic() { 27 static const int kNID = NID_sha256WithRSAEncryption; 28 static const char kShortName[] = "RSA-SHA256"; 29 static const char kLongName[] = "sha256WithRSAEncryption"; 30 static const char kText[] = "1.2.840.113549.1.1.11"; 31 static const uint8_t kDER[] = { 32 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 33 }; 34 35 CBS cbs; 36 CBS_init(&cbs, kDER, sizeof(kDER)); 37 if (OBJ_cbs2nid(&cbs) != kNID || 38 OBJ_sn2nid(kShortName) != kNID || 39 OBJ_ln2nid(kLongName) != kNID || 40 OBJ_txt2nid(kShortName) != kNID || 41 OBJ_txt2nid(kLongName) != kNID || 42 OBJ_txt2nid(kText) != kNID) { 43 return false; 44 } 45 46 if (strcmp(kShortName, OBJ_nid2sn(kNID)) != 0 || 47 strcmp(kLongName, OBJ_nid2ln(kNID)) != 0) { 48 return false; 49 } 50 51 if (OBJ_sn2nid("this is not an OID") != NID_undef || 52 OBJ_ln2nid("this is not an OID") != NID_undef || 53 OBJ_txt2nid("this is not an OID") != NID_undef) { 54 return false; 55 } 56 57 CBS_init(&cbs, NULL, 0); 58 if (OBJ_cbs2nid(&cbs) != NID_undef) { 59 return false; 60 } 61 62 // 1.2.840.113554.4.1.72585.2 (https://davidben.net/oid). 63 static const uint8_t kUnknownDER[] = { 64 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x02, 65 }; 66 CBS_init(&cbs, kUnknownDER, sizeof(kUnknownDER)); 67 if (OBJ_cbs2nid(&cbs) != NID_undef) { 68 return false; 69 } 70 71 return true; 72 } 73 74 static bool TestSignatureAlgorithms() { 75 int digest_nid, pkey_nid; 76 if (!OBJ_find_sigid_algs(NID_sha256WithRSAEncryption, &digest_nid, 77 &pkey_nid) || 78 digest_nid != NID_sha256 || pkey_nid != NID_rsaEncryption) { 79 return false; 80 } 81 82 if (OBJ_find_sigid_algs(NID_sha256, &digest_nid, &pkey_nid)) { 83 return false; 84 } 85 86 int sign_nid; 87 if (!OBJ_find_sigid_by_algs(&sign_nid, NID_sha256, NID_rsaEncryption) || 88 sign_nid != NID_sha256WithRSAEncryption) { 89 return false; 90 } 91 92 if (OBJ_find_sigid_by_algs(&sign_nid, NID_dsa, NID_rsaEncryption)) { 93 return false; 94 } 95 96 return true; 97 } 98 99 static bool ExpectObj2Txt(const uint8_t *der, size_t der_len, 100 bool always_return_oid, const char *expected) { 101 ASN1_OBJECT obj; 102 OPENSSL_memset(&obj, 0, sizeof(obj)); 103 obj.data = der; 104 obj.length = static_cast<int>(der_len); 105 106 int expected_len = static_cast<int>(strlen(expected)); 107 108 int len = OBJ_obj2txt(nullptr, 0, &obj, always_return_oid); 109 if (len != expected_len) { 110 fprintf(stderr, 111 "OBJ_obj2txt of %s with out_len = 0 returned %d, wanted %d.\n", 112 expected, len, expected_len); 113 return false; 114 } 115 116 char short_buf[1]; 117 OPENSSL_memset(short_buf, 0xff, sizeof(short_buf)); 118 len = OBJ_obj2txt(short_buf, sizeof(short_buf), &obj, always_return_oid); 119 if (len != expected_len) { 120 fprintf(stderr, 121 "OBJ_obj2txt of %s with out_len = 1 returned %d, wanted %d.\n", 122 expected, len, expected_len); 123 return false; 124 } 125 126 if (OPENSSL_memchr(short_buf, '\0', sizeof(short_buf)) == nullptr) { 127 fprintf(stderr, 128 "OBJ_obj2txt of %s with out_len = 1 did not NUL-terminate the " 129 "output.\n", 130 expected); 131 return false; 132 } 133 134 char buf[256]; 135 len = OBJ_obj2txt(buf, sizeof(buf), &obj, always_return_oid); 136 if (len != expected_len) { 137 fprintf(stderr, 138 "OBJ_obj2txt of %s with out_len = 256 returned %d, wanted %d.\n", 139 expected, len, expected_len); 140 return false; 141 } 142 143 if (strcmp(buf, expected) != 0) { 144 fprintf(stderr, "OBJ_obj2txt returned \"%s\"; wanted \"%s\".\n", buf, 145 expected); 146 return false; 147 } 148 149 return true; 150 } 151 152 static bool TestObj2Txt() { 153 // kSHA256WithRSAEncryption is the DER representation of 154 // 1.2.840.113549.1.1.11, id-sha256WithRSAEncryption. 155 static const uint8_t kSHA256WithRSAEncryption[] = { 156 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 157 }; 158 159 // kBasicConstraints is the DER representation of 2.5.29.19, 160 // id-basicConstraints. 161 static const uint8_t kBasicConstraints[] = { 162 0x55, 0x1d, 0x13, 163 }; 164 165 // kTestOID is the DER representation of 1.2.840.113554.4.1.72585.0, 166 // from https://davidben.net/oid. 167 static const uint8_t kTestOID[] = { 168 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00, 169 }; 170 171 if (!ExpectObj2Txt(kSHA256WithRSAEncryption, sizeof(kSHA256WithRSAEncryption), 172 true /* don't return name */, "1.2.840.113549.1.1.11") || 173 !ExpectObj2Txt(kSHA256WithRSAEncryption, sizeof(kSHA256WithRSAEncryption), 174 false /* return name */, "sha256WithRSAEncryption") || 175 !ExpectObj2Txt(kBasicConstraints, sizeof(kBasicConstraints), 176 true /* don't return name */, "2.5.29.19") || 177 !ExpectObj2Txt(kBasicConstraints, sizeof(kBasicConstraints), 178 false /* return name */, "X509v3 Basic Constraints") || 179 !ExpectObj2Txt(kTestOID, sizeof(kTestOID), true /* don't return name */, 180 "1.2.840.113554.4.1.72585.0") || 181 !ExpectObj2Txt(kTestOID, sizeof(kTestOID), false /* return name */, 182 "1.2.840.113554.4.1.72585.0") || 183 // Python depends on the empty OID successfully encoding as the empty 184 // string. 185 !ExpectObj2Txt(nullptr, 0, false /* return name */, "") || 186 !ExpectObj2Txt(nullptr, 0, true /* don't return name */, "")) { 187 return false; 188 } 189 190 ASN1_OBJECT obj; 191 OPENSSL_memset(&obj, 0, sizeof(obj)); 192 193 // kNonMinimalOID is kBasicConstraints with the final component non-minimally 194 // encoded. 195 static const uint8_t kNonMinimalOID[] = { 196 0x55, 0x1d, 0x80, 0x13, 197 }; 198 obj.data = kNonMinimalOID; 199 obj.length = sizeof(kNonMinimalOID); 200 if (OBJ_obj2txt(NULL, 0, &obj, 0) != -1) { 201 fprintf(stderr, "OBJ_obj2txt accepted non-minimal OIDs.\n"); 202 return false; 203 } 204 205 // kOverflowOID is the DER representation of 206 // 1.2.840.113554.4.1.72585.18446744073709551616. (The final value is 2^64.) 207 static const uint8_t kOverflowOID[] = { 208 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 209 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 210 }; 211 obj.data = kOverflowOID; 212 obj.length = sizeof(kOverflowOID); 213 if (OBJ_obj2txt(NULL, 0, &obj, 0) != -1) { 214 fprintf(stderr, "OBJ_obj2txt accepted an OID with a large component.\n"); 215 return false; 216 } 217 218 // kInvalidOID is a mis-encoded version of kBasicConstraints with the final 219 // octet having the high bit set. 220 static const uint8_t kInvalidOID[] = { 221 0x55, 0x1d, 0x93, 222 }; 223 obj.data = kInvalidOID; 224 obj.length = sizeof(kInvalidOID); 225 if (OBJ_obj2txt(NULL, 0, &obj, 0) != -1) { 226 fprintf(stderr, "OBJ_obj2txt accepted a mis-encoded OID.\n"); 227 return false; 228 } 229 230 return true; 231 } 232 233 int main() { 234 CRYPTO_library_init(); 235 236 if (!TestBasic() || 237 !TestSignatureAlgorithms() || 238 !TestObj2Txt()) { 239 return 1; 240 } 241 242 printf("PASS\n"); 243 return 0; 244 } 245