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 *
getCertError(PRErrorCode errNum)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
printChainFailure(CERTVerifyLog * log)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