security/pkix/lib/pkixkey.cpp

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
michael@0 3 /* Copyright 2013 Mozilla Foundation
michael@0 4 *
michael@0 5 * Licensed under the Apache License, Version 2.0 (the "License");
michael@0 6 * you may not use this file except in compliance with the License.
michael@0 7 * You may obtain a copy of the License at
michael@0 8 *
michael@0 9 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 10 *
michael@0 11 * Unless required by applicable law or agreed to in writing, software
michael@0 12 * distributed under the License is distributed on an "AS IS" BASIS,
michael@0 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
michael@0 14 * See the License for the specific language governing permissions and
michael@0 15 * limitations under the License.
michael@0 16 */
michael@0 17
michael@0 18 #include "pkix/pkix.h"
michael@0 19
michael@0 20 #include <limits>
michael@0 21 #include <stdint.h>
michael@0 22
michael@0 23 #include "cert.h"
michael@0 24 #include "cryptohi.h"
michael@0 25 #include "prerror.h"
michael@0 26 #include "secerr.h"
michael@0 27
michael@0 28 namespace mozilla { namespace pkix {
michael@0 29
michael@0 30 SECStatus
michael@0 31 VerifySignedData(const CERTSignedData* sd, const CERTCertificate* cert,
michael@0 32 void* pkcs11PinArg)
michael@0 33 {
michael@0 34 if (!sd || !sd->data.data || !sd->signatureAlgorithm.algorithm.data ||
michael@0 35 !sd->signature.data || !cert) {
michael@0 36 PR_NOT_REACHED("invalid args to VerifySignedData");
michael@0 37 PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
michael@0 38 return SECFailure;
michael@0 39 }
michael@0 40
michael@0 41 // See bug 921585.
michael@0 42 if (sd->data.len > static_cast<unsigned int>(std::numeric_limits<int>::max())) {
michael@0 43 PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
michael@0 44 return SECFailure;
michael@0 45 }
michael@0 46
michael@0 47 // convert sig->len from bit counts to byte count.
michael@0 48 SECItem sig = sd->signature;
michael@0 49 DER_ConvertBitString(&sig);
michael@0 50
michael@0 51 // Use SECKEY_ExtractPublicKey instead of CERT_ExtractPublicKey because
michael@0 52 // CERT_ExtractPublicKey would try to do (EC)DSA parameter inheritance, using
michael@0 53 // the classic (wrong) NSS path building logic. We intentionally do not
michael@0 54 // support parameter inheritance.
michael@0 55 ScopedSECKEYPublicKey
michael@0 56 pubKey(SECKEY_ExtractPublicKey(&cert->subjectPublicKeyInfo));
michael@0 57 if (!pubKey) {
michael@0 58 return SECFailure;
michael@0 59 }
michael@0 60
michael@0 61 SECOidTag hashAlg;
michael@0 62 if (VFY_VerifyDataWithAlgorithmID(sd->data.data, static_cast<int>(sd->data.len),
michael@0 63 pubKey.get(), &sig, &sd->signatureAlgorithm,
michael@0 64 &hashAlg, pkcs11PinArg) != SECSuccess) {
michael@0 65 return SECFailure;
michael@0 66 }
michael@0 67
michael@0 68 // TODO: Ideally, we would do this check before we call
michael@0 69 // VFY_VerifyDataWithAlgorithmID. But, VFY_VerifyDataWithAlgorithmID gives us
michael@0 70 // the hash algorithm so it is more convenient to do things in this order.
michael@0 71 uint32_t policy;
michael@0 72 if (NSS_GetAlgorithmPolicy(hashAlg, &policy) != SECSuccess) {
michael@0 73 return SECFailure;
michael@0 74 }
michael@0 75
michael@0 76 // XXX: I'm not sure why there isn't NSS_USE_ALG_IN_SSL_SIGNATURE, but there
michael@0 77 // isn't. Since we don't know the context in which we're being called, be as
michael@0 78 // strict as we can be given the NSS API that is available.
michael@0 79 static const uint32_t requiredPolicy = NSS_USE_ALG_IN_CERT_SIGNATURE |
michael@0 80 NSS_USE_ALG_IN_CMS_SIGNATURE;
michael@0 81 if ((policy & requiredPolicy) != requiredPolicy) {
michael@0 82 PR_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED, 0);
michael@0 83 return SECFailure;
michael@0 84 }
michael@0 85
michael@0 86 return SECSuccess;
michael@0 87 }
michael@0 88
michael@0 89 } } // namespace mozilla::pkix

mercurial