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 25 #include "secerr.h" 26 #include "sslerr.h" 27 #include "nspr.h" 28 #include "certt.h" 29 30 #include "../diagnose.hxx" 31 32 using namespace xmlsecurity; 33 34 struct ErrDesc { 35 PRErrorCode errNum; 36 const char * errString; 37 }; 38 39 40 41 const ErrDesc allDesc[] = { 42 43 #include "certerrors.h" 44 45 }; 46 47 48 49 /* Returns a UTF-8 encoded constant error string for "errNum". 50 * Returns NULL of errNum is unknown. 51 */ 52 const char * 53 getCertError(PRErrorCode errNum) 54 { 55 static char sEmpty[] = ""; 56 const int numDesc = sizeof(allDesc) / sizeof(ErrDesc); 57 for (int i = 0; i < numDesc; i++) 58 { 59 if (allDesc[i].errNum == errNum) 60 return allDesc[i].errString; 61 } 62 63 return sEmpty; 64 } 65 66 void 67 printChainFailure(CERTVerifyLog *log) 68 { 69 unsigned long errorFlags = 0; 70 unsigned int depth = (unsigned int)-1; 71 const char * specificError = NULL; 72 const char * issuer = NULL; 73 CERTVerifyLogNode *node = NULL; 74 75 if (log->count > 0) 76 { 77 xmlsec_trace("Bad certifcation path:"); 78 for (node = log->head; node; node = node->next) 79 { 80 if (depth != node->depth) 81 { 82 depth = node->depth; 83 xmlsec_trace("Certificate: %d. %s %s:", depth, 84 node->cert->subjectName, 85 depth ? "[Certificate Authority]": ""); 86 } 87 xmlsec_trace(" ERROR %ld: %s", node->error, 88 getCertError(node->error)); 89 specificError = NULL; 90 issuer = NULL; 91 switch (node->error) 92 { 93 case SEC_ERROR_INADEQUATE_KEY_USAGE: 94 errorFlags = (unsigned long)node->arg; 95 switch (errorFlags) 96 { 97 case KU_DIGITAL_SIGNATURE: 98 specificError = "Certificate cannot sign."; 99 break; 100 case KU_KEY_ENCIPHERMENT: 101 specificError = "Certificate cannot encrypt."; 102 break; 103 case KU_KEY_CERT_SIGN: 104 specificError = "Certificate cannot sign other certs."; 105 break; 106 default: 107 specificError = "[unknown usage]."; 108 break; 109 } 110 case SEC_ERROR_INADEQUATE_CERT_TYPE: 111 errorFlags = (unsigned long)node->arg; 112 switch (errorFlags) 113 { 114 case NS_CERT_TYPE_SSL_CLIENT: 115 case NS_CERT_TYPE_SSL_SERVER: 116 specificError = "Certificate cannot be used for SSL."; 117 break; 118 case NS_CERT_TYPE_SSL_CA: 119 specificError = "Certificate cannot be used as an SSL CA."; 120 break; 121 case NS_CERT_TYPE_EMAIL: 122 specificError = "Certificate cannot be used for SMIME."; 123 break; 124 case NS_CERT_TYPE_EMAIL_CA: 125 specificError = "Certificate cannot be used as an SMIME CA."; 126 break; 127 case NS_CERT_TYPE_OBJECT_SIGNING: 128 specificError = "Certificate cannot be used for object signing."; 129 break; 130 case NS_CERT_TYPE_OBJECT_SIGNING_CA: 131 specificError = "Certificate cannot be used as an object signing CA."; 132 break; 133 default: 134 specificError = "[unknown usage]."; 135 break; 136 } 137 case SEC_ERROR_UNKNOWN_ISSUER: 138 specificError = "Unknown issuer:"; 139 issuer = node->cert->issuerName; 140 break; 141 case SEC_ERROR_UNTRUSTED_ISSUER: 142 specificError = "Untrusted issuer:"; 143 issuer = node->cert->issuerName; 144 break; 145 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: 146 specificError = "Expired issuer certificate:"; 147 issuer = node->cert->issuerName; 148 break; 149 default: 150 break; 151 } 152 if (specificError) 153 xmlsec_trace("%s", specificError); 154 if (issuer) 155 xmlsec_trace("%s", issuer); 156 } 157 } 158 } 159