1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2008 by Sun Microsystems, Inc.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * $RCSfile: securityenvironment_nssimpl.cxx,v $
10  * $Revision: 1.23 $
11  *
12  * This file is part of OpenOffice.org.
13  *
14  * OpenOffice.org is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License version 3
16  * only, as published by the Free Software Foundation.
17  *
18  * OpenOffice.org is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU Lesser General Public License version 3 for more details
22  * (a copy is included in the LICENSE file that accompanied this code).
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * version 3 along with OpenOffice.org.  If not, see
26  * <http://www.openoffice.org/license.html>
27  * for a copy of the LGPLv3 License.
28  *
29  ************************************************************************/
30 
31 
32 #include "secerr.h"
33 #include "sslerr.h"
34 #include "nspr.h"
35 #include "certt.h"
36 
37 #include "../diagnose.hxx"
38 
39 using namespace xmlsecurity;
40 
41 struct ErrDesc {
42     PRErrorCode	 errNum;
43     const char * errString;
44 };
45 
46 
47 
48 const ErrDesc allDesc[] = {
49 
50 #include "certerrors.h"
51 
52 };
53 
54 
55 
56 /* Returns a UTF-8 encoded constant error string for "errNum".
57  * Returns NULL of errNum is unknown.
58  */
59 const char *
60 getCertError(PRErrorCode errNum)
61 {
62     static char sEmpty[] = "";
63     const int numDesc = sizeof(allDesc) / sizeof(ErrDesc);
64     for (int i = 0; i < numDesc; i++)
65     {
66         if (allDesc[i].errNum == errNum)
67             return  allDesc[i].errString;
68     }
69 
70     return sEmpty;
71 }
72 
73 void
74 printChainFailure(CERTVerifyLog *log)
75 {
76     unsigned long errorFlags  = 0;
77     unsigned int       depth  = (unsigned int)-1;
78     const char * specificError = NULL;
79     const char * issuer = NULL;
80     CERTVerifyLogNode *node   = NULL;
81 
82     if (log->count > 0)
83     {
84         xmlsec_trace("Bad certifcation path:");
85         for (node = log->head; node; node = node->next)
86         {
87             if (depth != node->depth)
88             {
89                 depth = node->depth;
90                 xmlsec_trace("Certificate:  %d. %s %s:", depth,
91                         node->cert->subjectName,
92                         depth ? "[Certificate Authority]": "");
93             }
94             xmlsec_trace("  ERROR %ld: %s", node->error,
95                     getCertError(node->error));
96             specificError = NULL;
97             issuer = NULL;
98             switch (node->error)
99             {
100             case SEC_ERROR_INADEQUATE_KEY_USAGE:
101                 errorFlags = (unsigned long)node->arg;
102                 switch (errorFlags)
103                 {
104                 case KU_DIGITAL_SIGNATURE:
105                     specificError = "Certificate cannot sign.";
106                     break;
107                 case KU_KEY_ENCIPHERMENT:
108                     specificError = "Certificate cannot encrypt.";
109                     break;
110                 case KU_KEY_CERT_SIGN:
111                     specificError = "Certificate cannot sign other certs.";
112                     break;
113                 default:
114                     specificError = "[unknown usage].";
115                     break;
116                 }
117             case SEC_ERROR_INADEQUATE_CERT_TYPE:
118                 errorFlags = (unsigned long)node->arg;
119                 switch (errorFlags)
120                 {
121                 case NS_CERT_TYPE_SSL_CLIENT:
122                 case NS_CERT_TYPE_SSL_SERVER:
123                     specificError = "Certificate cannot be used for SSL.";
124                     break;
125                 case NS_CERT_TYPE_SSL_CA:
126                     specificError = "Certificate cannot be used as an SSL CA.";
127                     break;
128                 case NS_CERT_TYPE_EMAIL:
129                     specificError = "Certificate cannot be used for SMIME.";
130                     break;
131                 case NS_CERT_TYPE_EMAIL_CA:
132                     specificError = "Certificate cannot be used as an SMIME CA.";
133                     break;
134                 case NS_CERT_TYPE_OBJECT_SIGNING:
135                     specificError = "Certificate cannot be used for object signing.";
136                     break;
137                 case NS_CERT_TYPE_OBJECT_SIGNING_CA:
138                     specificError = "Certificate cannot be used as an object signing CA.";
139                     break;
140                 default:
141                     specificError = "[unknown usage].";
142                     break;
143                 }
144             case SEC_ERROR_UNKNOWN_ISSUER:
145                 specificError = "Unknown issuer:";
146                 issuer = node->cert->issuerName;
147                 break;
148             case SEC_ERROR_UNTRUSTED_ISSUER:
149                 specificError = "Untrusted issuer:";
150                 issuer = node->cert->issuerName;
151                 break;
152             case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
153                 specificError = "Expired issuer certificate:";
154                 issuer = node->cert->issuerName;
155                 break;
156             default:
157                 break;
158             }
159             if (specificError)
160                 xmlsec_trace("%s", specificError);
161             if (issuer)
162                 xmlsec_trace("%s", issuer);
163         }
164     }
165 }
166