1 /* 2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <stdint.h> 29 #include <errno.h> 30 31 #include "brssl.h" 32 #include "bearssl.h" 33 34 static struct { 35 int err; 36 const char *name; 37 const char *comment; 38 } errors[] = { 39 { 40 BR_ERR_BAD_PARAM, 41 "BR_ERR_BAD_PARAM", 42 "Caller-provided parameter is incorrect." 43 }, { 44 BR_ERR_BAD_STATE, 45 "BR_ERR_BAD_STATE", 46 "Operation requested by the caller cannot be applied with" 47 " the current context state (e.g. reading data while" 48 " outgoing data is waiting to be sent)." 49 }, { 50 BR_ERR_UNSUPPORTED_VERSION, 51 "BR_ERR_UNSUPPORTED_VERSION", 52 "Incoming protocol or record version is unsupported." 53 }, { 54 BR_ERR_BAD_VERSION, 55 "BR_ERR_BAD_VERSION", 56 "Incoming record version does not match the expected version." 57 }, { 58 BR_ERR_BAD_LENGTH, 59 "BR_ERR_BAD_LENGTH", 60 "Incoming record length is invalid." 61 }, { 62 BR_ERR_TOO_LARGE, 63 "BR_ERR_TOO_LARGE", 64 "Incoming record is too large to be processed, or buffer" 65 " is too small for the handshake message to send." 66 }, { 67 BR_ERR_BAD_MAC, 68 "BR_ERR_BAD_MAC", 69 "Decryption found an invalid padding, or the record MAC is" 70 " not correct." 71 }, { 72 BR_ERR_NO_RANDOM, 73 "BR_ERR_NO_RANDOM", 74 "No initial entropy was provided, and none can be obtained" 75 " from the OS." 76 }, { 77 BR_ERR_UNKNOWN_TYPE, 78 "BR_ERR_UNKNOWN_TYPE", 79 "Incoming record type is unknown." 80 }, { 81 BR_ERR_UNEXPECTED, 82 "BR_ERR_UNEXPECTED", 83 "Incoming record or message has wrong type with regards to" 84 " the current engine state." 85 }, { 86 BR_ERR_BAD_CCS, 87 "BR_ERR_BAD_CCS", 88 "ChangeCipherSpec message from the peer has invalid contents." 89 }, { 90 BR_ERR_BAD_ALERT, 91 "BR_ERR_BAD_ALERT", 92 "Alert message from the peer has invalid contents" 93 " (odd length)." 94 }, { 95 BR_ERR_BAD_HANDSHAKE, 96 "BR_ERR_BAD_HANDSHAKE", 97 "Incoming handshake message decoding failed." 98 }, { 99 BR_ERR_OVERSIZED_ID, 100 "BR_ERR_OVERSIZED_ID", 101 "ServerHello contains a session ID which is larger than" 102 " 32 bytes." 103 }, { 104 BR_ERR_BAD_CIPHER_SUITE, 105 "BR_ERR_BAD_CIPHER_SUITE", 106 "Server wants to use a cipher suite that we did not claim" 107 " to support. This is also reported if we tried to advertise" 108 " a cipher suite that we do not support." 109 }, { 110 BR_ERR_BAD_COMPRESSION, 111 "BR_ERR_BAD_COMPRESSION", 112 "Server wants to use a compression that we did not claim" 113 " to support." 114 }, { 115 BR_ERR_BAD_FRAGLEN, 116 "BR_ERR_BAD_FRAGLEN", 117 "Server's max fragment length does not match client's." 118 }, { 119 BR_ERR_BAD_SECRENEG, 120 "BR_ERR_BAD_SECRENEG", 121 "Secure renegotiation failed." 122 }, { 123 BR_ERR_EXTRA_EXTENSION, 124 "BR_ERR_EXTRA_EXTENSION", 125 "Server sent an extension type that we did not announce," 126 " or used the same extension type several times in a" 127 " single ServerHello." 128 }, { 129 BR_ERR_BAD_SNI, 130 "BR_ERR_BAD_SNI", 131 "Invalid Server Name Indication contents (when used by" 132 " the server, this extension shall be empty)." 133 }, { 134 BR_ERR_BAD_HELLO_DONE, 135 "BR_ERR_BAD_HELLO_DONE", 136 "Invalid ServerHelloDone from the server (length is not 0)." 137 }, { 138 BR_ERR_LIMIT_EXCEEDED, 139 "BR_ERR_LIMIT_EXCEEDED", 140 "Internal limit exceeded (e.g. server's public key is too" 141 " large)." 142 }, { 143 BR_ERR_BAD_FINISHED, 144 "BR_ERR_BAD_FINISHED", 145 "Finished message from peer does not match the expected" 146 " value." 147 }, { 148 BR_ERR_RESUME_MISMATCH, 149 "BR_ERR_RESUME_MISMATCH", 150 "Session resumption attempt with distinct version or cipher" 151 " suite." 152 }, { 153 BR_ERR_INVALID_ALGORITHM, 154 "BR_ERR_INVALID_ALGORITHM", 155 "Unsupported or invalid algorithm (ECDHE curve, signature" 156 " algorithm, hash function)." 157 }, { 158 BR_ERR_BAD_SIGNATURE, 159 "BR_ERR_BAD_SIGNATURE", 160 "Invalid signature in ServerKeyExchange or" 161 " CertificateVerify message." 162 }, { 163 BR_ERR_WRONG_KEY_USAGE, 164 "BR_ERR_WRONG_KEY_USAGE", 165 "Peer's public key does not have the proper type or is" 166 " not allowed for the requested operation." 167 }, { 168 BR_ERR_NO_CLIENT_AUTH, 169 "BR_ERR_NO_CLIENT_AUTH", 170 "Client did not send a certificate upon request, or the" 171 " client certificate could not be validated." 172 }, { 173 BR_ERR_IO, 174 "BR_ERR_IO", 175 "I/O error or premature close on transport stream." 176 }, { 177 BR_ERR_X509_INVALID_VALUE, 178 "BR_ERR_X509_INVALID_VALUE", 179 "Invalid value in an ASN.1 structure." 180 }, 181 { 182 BR_ERR_X509_TRUNCATED, 183 "BR_ERR_X509_TRUNCATED", 184 "Truncated certificate or other ASN.1 object." 185 }, 186 { 187 BR_ERR_X509_EMPTY_CHAIN, 188 "BR_ERR_X509_EMPTY_CHAIN", 189 "Empty certificate chain (no certificate at all)." 190 }, 191 { 192 BR_ERR_X509_INNER_TRUNC, 193 "BR_ERR_X509_INNER_TRUNC", 194 "Decoding error: inner element extends beyond outer element" 195 " size." 196 }, 197 { 198 BR_ERR_X509_BAD_TAG_CLASS, 199 "BR_ERR_X509_BAD_TAG_CLASS", 200 "Decoding error: unsupported tag class (application or" 201 " private)." 202 }, 203 { 204 BR_ERR_X509_BAD_TAG_VALUE, 205 "BR_ERR_X509_BAD_TAG_VALUE", 206 "Decoding error: unsupported tag value." 207 }, 208 { 209 BR_ERR_X509_INDEFINITE_LENGTH, 210 "BR_ERR_X509_INDEFINITE_LENGTH", 211 "Decoding error: indefinite length." 212 }, 213 { 214 BR_ERR_X509_EXTRA_ELEMENT, 215 "BR_ERR_X509_EXTRA_ELEMENT", 216 "Decoding error: extraneous element." 217 }, 218 { 219 BR_ERR_X509_UNEXPECTED, 220 "BR_ERR_X509_UNEXPECTED", 221 "Decoding error: unexpected element." 222 }, 223 { 224 BR_ERR_X509_NOT_CONSTRUCTED, 225 "BR_ERR_X509_NOT_CONSTRUCTED", 226 "Decoding error: expected constructed element, but is" 227 " primitive." 228 }, 229 { 230 BR_ERR_X509_NOT_PRIMITIVE, 231 "BR_ERR_X509_NOT_PRIMITIVE", 232 "Decoding error: expected primitive element, but is" 233 " constructed." 234 }, 235 { 236 BR_ERR_X509_PARTIAL_BYTE, 237 "BR_ERR_X509_PARTIAL_BYTE", 238 "Decoding error: BIT STRING length is not multiple of 8." 239 }, 240 { 241 BR_ERR_X509_BAD_BOOLEAN, 242 "BR_ERR_X509_BAD_BOOLEAN", 243 "Decoding error: BOOLEAN value has invalid length." 244 }, 245 { 246 BR_ERR_X509_OVERFLOW, 247 "BR_ERR_X509_OVERFLOW", 248 "Decoding error: value is off-limits." 249 }, 250 { 251 BR_ERR_X509_BAD_DN, 252 "BR_ERR_X509_BAD_DN", 253 "Invalid distinguished name." 254 }, 255 { 256 BR_ERR_X509_BAD_TIME, 257 "BR_ERR_X509_BAD_TIME", 258 "Invalid date/time representation." 259 }, 260 { 261 BR_ERR_X509_UNSUPPORTED, 262 "BR_ERR_X509_UNSUPPORTED", 263 "Certificate contains unsupported features that cannot be" 264 " ignored." 265 }, 266 { 267 BR_ERR_X509_LIMIT_EXCEEDED, 268 "BR_ERR_X509_LIMIT_EXCEEDED", 269 "Key or signature size exceeds internal limits." 270 }, 271 { 272 BR_ERR_X509_WRONG_KEY_TYPE, 273 "BR_ERR_X509_WRONG_KEY_TYPE", 274 "Key type does not match that which was expected." 275 }, 276 { 277 BR_ERR_X509_BAD_SIGNATURE, 278 "BR_ERR_X509_BAD_SIGNATURE", 279 "Signature is invalid." 280 }, 281 { 282 BR_ERR_X509_TIME_UNKNOWN, 283 "BR_ERR_X509_TIME_UNKNOWN", 284 "Validation time is unknown." 285 }, 286 { 287 BR_ERR_X509_EXPIRED, 288 "BR_ERR_X509_EXPIRED", 289 "Certificate is expired or not yet valid." 290 }, 291 { 292 BR_ERR_X509_DN_MISMATCH, 293 "BR_ERR_X509_DN_MISMATCH", 294 "Issuer/Subject DN mismatch in the chain." 295 }, 296 { 297 BR_ERR_X509_BAD_SERVER_NAME, 298 "BR_ERR_X509_BAD_SERVER_NAME", 299 "Expected server name was not found in the chain." 300 }, 301 { 302 BR_ERR_X509_CRITICAL_EXTENSION, 303 "BR_ERR_X509_CRITICAL_EXTENSION", 304 "Unknown critical extension in certificate." 305 }, 306 { 307 BR_ERR_X509_NOT_CA, 308 "BR_ERR_X509_NOT_CA", 309 "Not a CA, or path length constraint violation." 310 }, 311 { 312 BR_ERR_X509_FORBIDDEN_KEY_USAGE, 313 "BR_ERR_X509_FORBIDDEN_KEY_USAGE", 314 "Key Usage extension prohibits intended usage." 315 }, 316 { 317 BR_ERR_X509_WEAK_PUBLIC_KEY, 318 "BR_ERR_X509_WEAK_PUBLIC_KEY", 319 "Public key found in certificate is too small." 320 }, 321 { 322 BR_ERR_X509_NOT_TRUSTED, 323 "BR_ERR_X509_NOT_TRUSTED", 324 "Chain could not be linked to a trust anchor." 325 }, 326 { 0, 0, 0 } 327 }; 328 329 /* see brssl.h */ 330 const char * 331 find_error_name(int err, const char **comment) 332 { 333 size_t u; 334 335 for (u = 0; errors[u].name; u ++) { 336 if (errors[u].err == err) { 337 if (comment != NULL) { 338 *comment = errors[u].comment; 339 } 340 return errors[u].name; 341 } 342 } 343 return NULL; 344 } 345