security/manager/ssl/src/nsDataSignatureVerifier.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "nsDataSignatureVerifier.h"
michael@0 6 #include "nsCOMPtr.h"
michael@0 7 #include "nsString.h"
michael@0 8
michael@0 9 #include "seccomon.h"
michael@0 10 #include "nssb64.h"
michael@0 11 #include "certt.h"
michael@0 12 #include "keyhi.h"
michael@0 13 #include "cryptohi.h"
michael@0 14
michael@0 15 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
michael@0 16
michael@0 17 NS_IMPL_ISUPPORTS(nsDataSignatureVerifier, nsIDataSignatureVerifier)
michael@0 18
michael@0 19 const SEC_ASN1Template CERT_SignatureDataTemplate[] =
michael@0 20 {
michael@0 21 { SEC_ASN1_SEQUENCE,
michael@0 22 0, nullptr, sizeof(CERTSignedData) },
michael@0 23 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
michael@0 24 offsetof(CERTSignedData,signatureAlgorithm),
michael@0 25 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate), },
michael@0 26 { SEC_ASN1_BIT_STRING,
michael@0 27 offsetof(CERTSignedData,signature), },
michael@0 28 { 0, }
michael@0 29 };
michael@0 30
michael@0 31 NS_IMETHODIMP
michael@0 32 nsDataSignatureVerifier::VerifyData(const nsACString & aData,
michael@0 33 const nsACString & aSignature,
michael@0 34 const nsACString & aPublicKey,
michael@0 35 bool *_retval)
michael@0 36 {
michael@0 37 // Allocate an arena to handle the majority of the allocations
michael@0 38 PLArenaPool *arena;
michael@0 39 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
michael@0 40 if (!arena)
michael@0 41 return NS_ERROR_OUT_OF_MEMORY;
michael@0 42
michael@0 43 // Base 64 decode the key
michael@0 44 SECItem keyItem;
michael@0 45 PORT_Memset(&keyItem, 0, sizeof(SECItem));
michael@0 46 if (!NSSBase64_DecodeBuffer(arena, &keyItem,
michael@0 47 nsPromiseFlatCString(aPublicKey).get(),
michael@0 48 aPublicKey.Length())) {
michael@0 49 PORT_FreeArena(arena, false);
michael@0 50 return NS_ERROR_FAILURE;
michael@0 51 }
michael@0 52
michael@0 53 // Extract the public key from the data
michael@0 54 CERTSubjectPublicKeyInfo *pki = SECKEY_DecodeDERSubjectPublicKeyInfo(&keyItem);
michael@0 55 if (!pki) {
michael@0 56 PORT_FreeArena(arena, false);
michael@0 57 return NS_ERROR_FAILURE;
michael@0 58 }
michael@0 59 SECKEYPublicKey *publicKey = SECKEY_ExtractPublicKey(pki);
michael@0 60 SECKEY_DestroySubjectPublicKeyInfo(pki);
michael@0 61 pki = nullptr;
michael@0 62
michael@0 63 if (!publicKey) {
michael@0 64 PORT_FreeArena(arena, false);
michael@0 65 return NS_ERROR_FAILURE;
michael@0 66 }
michael@0 67
michael@0 68 // Base 64 decode the signature
michael@0 69 SECItem signatureItem;
michael@0 70 PORT_Memset(&signatureItem, 0, sizeof(SECItem));
michael@0 71 if (!NSSBase64_DecodeBuffer(arena, &signatureItem,
michael@0 72 nsPromiseFlatCString(aSignature).get(),
michael@0 73 aSignature.Length())) {
michael@0 74 SECKEY_DestroyPublicKey(publicKey);
michael@0 75 PORT_FreeArena(arena, false);
michael@0 76 return NS_ERROR_FAILURE;
michael@0 77 }
michael@0 78
michael@0 79 // Decode the signature and algorithm
michael@0 80 CERTSignedData sigData;
michael@0 81 PORT_Memset(&sigData, 0, sizeof(CERTSignedData));
michael@0 82 SECStatus ss = SEC_QuickDERDecodeItem(arena, &sigData,
michael@0 83 CERT_SignatureDataTemplate,
michael@0 84 &signatureItem);
michael@0 85 if (ss != SECSuccess) {
michael@0 86 SECKEY_DestroyPublicKey(publicKey);
michael@0 87 PORT_FreeArena(arena, false);
michael@0 88 return NS_ERROR_FAILURE;
michael@0 89 }
michael@0 90
michael@0 91 // Perform the final verification
michael@0 92 DER_ConvertBitString(&(sigData.signature));
michael@0 93 ss = VFY_VerifyDataWithAlgorithmID((const unsigned char*)nsPromiseFlatCString(aData).get(),
michael@0 94 aData.Length(), publicKey,
michael@0 95 &(sigData.signature),
michael@0 96 &(sigData.signatureAlgorithm),
michael@0 97 nullptr, nullptr);
michael@0 98
michael@0 99 // Clean up remaining objects
michael@0 100 SECKEY_DestroyPublicKey(publicKey);
michael@0 101 PORT_FreeArena(arena, false);
michael@0 102
michael@0 103 *_retval = (ss == SECSuccess);
michael@0 104
michael@0 105 return NS_OK;
michael@0 106 }

mercurial