1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "secerr.h" 25 #include "sslerr.h" 26 #include "nspr.h" 27 #include "certt.h" 28 29 #include "../diagnose.hxx" 30 31 using namespace xmlsecurity; 32 33 struct ErrDesc { 34 PRErrorCode errNum; 35 const char * errString; 36 }; 37 38 39 40 const ErrDesc allDesc[] = { 41 42 #include "certerrors.h" 43 44 }; 45 46 47 48 /* Returns a UTF-8 encoded constant error string for "errNum". 49 * Returns NULL of errNum is unknown. 50 */ 51 const char * 52 getCertError(PRErrorCode errNum) 53 { 54 static char sEmpty[] = ""; 55 const int numDesc = sizeof(allDesc) / sizeof(ErrDesc); 56 for (int i = 0; i < numDesc; i++) 57 { 58 if (allDesc[i].errNum == errNum) 59 return allDesc[i].errString; 60 } 61 62 return sEmpty; 63 } 64 65 void 66 printChainFailure(CERTVerifyLog *log) 67 { 68 unsigned long errorFlags = 0; 69 unsigned int depth = (unsigned int)-1; 70 const char * specificError = NULL; 71 const char * issuer = NULL; 72 CERTVerifyLogNode *node = NULL; 73 74 if (log->count > 0) 75 { 76 xmlsec_trace("Bad certification path:"); 77 for (node = log->head; node; node = node->next) 78 { 79 if (depth != node->depth) 80 { 81 depth = node->depth; 82 xmlsec_trace("Certificate: %d. %s %s:", depth, 83 node->cert->subjectName, 84 depth ? "[Certificate Authority]": ""); 85 } 86 xmlsec_trace(" ERROR %ld: %s", node->error, 87 getCertError(node->error)); 88 specificError = NULL; 89 issuer = NULL; 90 switch (node->error) 91 { 92 case SEC_ERROR_INADEQUATE_KEY_USAGE: 93 errorFlags = (unsigned long)node->arg; 94 switch (errorFlags) 95 { 96 case KU_DIGITAL_SIGNATURE: 97 specificError = "Certificate cannot sign."; 98 break; 99 case KU_KEY_ENCIPHERMENT: 100 specificError = "Certificate cannot encrypt."; 101 break; 102 case KU_KEY_CERT_SIGN: 103 specificError = "Certificate cannot sign other certs."; 104 break; 105 default: 106 specificError = "[unknown usage]."; 107 break; 108 } 109 case SEC_ERROR_INADEQUATE_CERT_TYPE: 110 errorFlags = (unsigned long)node->arg; 111 switch (errorFlags) 112 { 113 case NS_CERT_TYPE_SSL_CLIENT: 114 case NS_CERT_TYPE_SSL_SERVER: 115 specificError = "Certificate cannot be used for SSL."; 116 break; 117 case NS_CERT_TYPE_SSL_CA: 118 specificError = "Certificate cannot be used as an SSL CA."; 119 break; 120 case NS_CERT_TYPE_EMAIL: 121 specificError = "Certificate cannot be used for SMIME."; 122 break; 123 case NS_CERT_TYPE_EMAIL_CA: 124 specificError = "Certificate cannot be used as an SMIME CA."; 125 break; 126 case NS_CERT_TYPE_OBJECT_SIGNING: 127 specificError = "Certificate cannot be used for object signing."; 128 break; 129 case NS_CERT_TYPE_OBJECT_SIGNING_CA: 130 specificError = "Certificate cannot be used as an object signing CA."; 131 break; 132 default: 133 specificError = "[unknown usage]."; 134 break; 135 } 136 case SEC_ERROR_UNKNOWN_ISSUER: 137 specificError = "Unknown issuer:"; 138 issuer = node->cert->issuerName; 139 break; 140 case SEC_ERROR_UNTRUSTED_ISSUER: 141 specificError = "Untrusted issuer:"; 142 issuer = node->cert->issuerName; 143 break; 144 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: 145 specificError = "Expired issuer certificate:"; 146 issuer = node->cert->issuerName; 147 break; 148 default: 149 break; 150 } 151 if (specificError) 152 xmlsec_trace("%s", specificError); 153 if (issuer) 154 xmlsec_trace("%s", issuer); 155 } 156 } 157 } 158