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.

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

mercurial