Back to index

lightning-sunbird  0.9+nobinonly
nsUsageArrayHelper.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *  John Gardiner Myers <jgmyers@speakeasy.net>
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsUsageArrayHelper.h"
00039 
00040 #include "nsCOMPtr.h"
00041 #include "nsIDateTimeFormat.h"
00042 #include "nsDateTimeFormatCID.h"
00043 #include "nsComponentManagerUtils.h"
00044 #include "nsReadableUtils.h"
00045 #include "nsNSSCertificate.h"
00046 
00047 #include "nspr.h"
00048 #include "nsNSSCertHeader.h"
00049 
00050 extern "C" {
00051 #include "secerr.h"
00052 }
00053 
00054 static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
00055 
00056 nsUsageArrayHelper::nsUsageArrayHelper(CERTCertificate *aCert)
00057 :mCert(aCert)
00058 {
00059   nsNSSShutDownPreventionLock locker;
00060   defaultcertdb = CERT_GetDefaultCertDB();
00061   nssComponent = do_GetService(kNSSComponentCID, &m_rv);
00062 }
00063 
00064 void
00065 nsUsageArrayHelper::check(const char *suffix,
00066                         SECCertificateUsage aCertUsage,
00067                         PRUint32 &aCounter,
00068                         PRUnichar **outUsages)
00069 {
00070   if (!aCertUsage) return;
00071   nsCAutoString typestr;
00072   switch (aCertUsage) {
00073   case certificateUsageSSLClient:
00074     typestr = "VerifySSLClient";
00075     break;
00076   case certificateUsageSSLServer:
00077     typestr = "VerifySSLServer";
00078     break;
00079   case certificateUsageSSLServerWithStepUp:
00080     typestr = "VerifySSLStepUp";
00081     break;
00082   case certificateUsageEmailSigner:
00083     typestr = "VerifyEmailSigner";
00084     break;
00085   case certificateUsageEmailRecipient:
00086     typestr = "VerifyEmailRecip";
00087     break;
00088   case certificateUsageObjectSigner:
00089     typestr = "VerifyObjSign";
00090     break;
00091   case certificateUsageProtectedObjectSigner:
00092     typestr = "VerifyProtectObjSign";
00093     break;
00094   case certificateUsageUserCertImport:
00095     typestr = "VerifyUserImport";
00096     break;
00097   case certificateUsageSSLCA:
00098     typestr = "VerifySSLCA";
00099     break;
00100   case certificateUsageVerifyCA:
00101     typestr = "VerifyCAVerifier";
00102     break;
00103   case certificateUsageStatusResponder:
00104     typestr = "VerifyStatusResponder";
00105     break;
00106   case certificateUsageAnyCA:
00107     typestr = "VerifyAnyCA";
00108     break;
00109   default:
00110     break;
00111   }
00112   if (!typestr.IsEmpty()) {
00113     typestr.Append(suffix);
00114     nsAutoString verifyDesc;
00115     m_rv = nssComponent->GetPIPNSSBundleString(typestr.get(), verifyDesc);
00116     if (NS_SUCCEEDED(m_rv)) {
00117       outUsages[aCounter++] = ToNewUnicode(verifyDesc);
00118     }
00119   }
00120 }
00121 
00122 void
00123 nsUsageArrayHelper::verifyFailed(PRUint32 *_verified, int err)
00124 {
00125   switch (err) {
00126   /* For these cases, verify only failed for the particular usage */
00127   case SEC_ERROR_INADEQUATE_KEY_USAGE:
00128   case SEC_ERROR_INADEQUATE_CERT_TYPE:
00129     *_verified = nsNSSCertificate::USAGE_NOT_ALLOWED; break;
00130   /* These are the cases that have individual error messages */
00131   case SEC_ERROR_REVOKED_CERTIFICATE:
00132     *_verified = nsNSSCertificate::CERT_REVOKED; break;
00133   case SEC_ERROR_EXPIRED_CERTIFICATE:
00134     *_verified = nsNSSCertificate::CERT_EXPIRED; break;
00135   case SEC_ERROR_UNTRUSTED_CERT:
00136     *_verified = nsNSSCertificate::CERT_NOT_TRUSTED; break;
00137   case SEC_ERROR_UNTRUSTED_ISSUER:
00138     *_verified = nsNSSCertificate::ISSUER_NOT_TRUSTED; break;
00139   case SEC_ERROR_UNKNOWN_ISSUER:
00140     *_verified = nsNSSCertificate::ISSUER_UNKNOWN; break;
00141   case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
00142     // XXX are there other error for this?
00143     *_verified = nsNSSCertificate::INVALID_CA; break;
00144   case SEC_ERROR_CERT_USAGES_INVALID: // XXX what is this?
00145   // there are some OCSP errors from PSM 1.x to add here
00146   case SECSuccess:
00147     // this means, no verification result has ever been received
00148   default:
00149     *_verified = nsNSSCertificate::NOT_VERIFIED_UNKNOWN; break;
00150   }
00151 }
00152 
00153 nsresult
00154 nsUsageArrayHelper::GetUsagesArray(const char *suffix,
00155                       PRBool ignoreOcsp,
00156                       PRUint32 outArraySize,
00157                       PRUint32 *_verified,
00158                       PRUint32 *_count,
00159                       PRUnichar **outUsages)
00160 {
00161   nsNSSShutDownPreventionLock locker;
00162   if (NS_FAILED(m_rv))
00163     return m_rv;
00164 
00165   if (outArraySize < max_returned_out_array_size)
00166     return NS_ERROR_FAILURE;
00167 
00168   nsCOMPtr<nsINSSComponent> nssComponent;
00169 
00170   if (ignoreOcsp) {
00171     nsresult rv;
00172     nssComponent = do_GetService(kNSSComponentCID, &rv);
00173     if (NS_FAILED(rv))
00174       return rv;
00175     
00176     if (nssComponent) {
00177       nssComponent->SkipOcsp();
00178     }
00179   }
00180 
00181   PRUint32 &count = *_count;
00182   count = 0;
00183   SECCertificateUsage usages;
00184   
00185   CERT_VerifyCertificateNow(defaultcertdb, mCert, PR_TRUE, 
00186                          certificateUsageSSLClient |
00187                          certificateUsageSSLServer |
00188                          certificateUsageSSLServerWithStepUp |
00189                          certificateUsageEmailSigner |
00190                          certificateUsageEmailRecipient |
00191                          certificateUsageObjectSigner |
00192                          certificateUsageSSLCA |
00193                          certificateUsageStatusResponder,
00194                          NULL, &usages);
00195   int err = PR_GetError();
00196 
00197   // The following list of checks must be < max_returned_out_array_size
00198   
00199   check(suffix, usages & certificateUsageSSLClient, count, outUsages);
00200   check(suffix, usages & certificateUsageSSLServer, count, outUsages);
00201   check(suffix, usages & certificateUsageSSLServerWithStepUp, count, outUsages);
00202   check(suffix, usages & certificateUsageEmailSigner, count, outUsages);
00203   check(suffix, usages & certificateUsageEmailRecipient, count, outUsages);
00204   check(suffix, usages & certificateUsageObjectSigner, count, outUsages);
00205 #if 0
00206   check(suffix, usages & certificateUsageProtectedObjectSigner, count, outUsages);
00207   check(suffix, usages & certificateUsageUserCertImport, count, outUsages);
00208 #endif
00209   check(suffix, usages & certificateUsageSSLCA, count, outUsages);
00210 #if 0
00211   check(suffix, usages & certificateUsageVerifyCA, count, outUsages);
00212 #endif
00213   check(suffix, usages & certificateUsageStatusResponder, count, outUsages);
00214 #if 0
00215   check(suffix, usages & certificateUsageAnyCA, count, outUsages);
00216 #endif
00217 
00218   if (ignoreOcsp && nssComponent) {
00219     nssComponent->SkipOcspOff();
00220   }
00221 
00222   if (count == 0) {
00223     verifyFailed(_verified, err);
00224   } else {
00225     *_verified = nsNSSCertificate::VERIFIED_OK;
00226   }
00227   return NS_OK;
00228 }