From 99158494a1bde31dde5228215f665f4dcb8be904 Mon Sep 17 00:00:00 2001 From: "dtownsend%oxymoronical.com" Date: Mon, 3 Sep 2007 17:32:41 +0000 Subject: [PATCH] Bug 390615: Add scriptable interface to verify digital signatures. r=kaie, a=blocking-1.9 git-svn-id: svn://10.0.0.236/trunk@233809 18797224-902f-48f8-a5cc-f745e15eee43 --- .../security/manager/ssl/public/Makefile.in | 1 + .../ssl/public/nsIDataSignatureVerifier.idl | 58 ++++++ mozilla/security/manager/ssl/src/Makefile.in | 3 +- .../ssl/src/nsDataSignatureVerifier.cpp | 134 ++++++++++++ .../manager/ssl/src/nsDataSignatureVerifier.h | 63 ++++++ .../security/manager/ssl/src/nsNSSModule.cpp | 9 + .../ssl/tests/test_datasignatureverifier.js | 195 ++++++++++++++++++ 7 files changed, 462 insertions(+), 1 deletion(-) create mode 100644 mozilla/security/manager/ssl/public/nsIDataSignatureVerifier.idl create mode 100644 mozilla/security/manager/ssl/src/nsDataSignatureVerifier.cpp create mode 100644 mozilla/security/manager/ssl/src/nsDataSignatureVerifier.h create mode 100644 mozilla/security/manager/ssl/tests/test_datasignatureverifier.js diff --git a/mozilla/security/manager/ssl/public/Makefile.in b/mozilla/security/manager/ssl/public/Makefile.in index fcd4503ac46..e22b745af41 100644 --- a/mozilla/security/manager/ssl/public/Makefile.in +++ b/mozilla/security/manager/ssl/public/Makefile.in @@ -94,6 +94,7 @@ XPIDLSRCS = \ nsICipherInfo.idl \ nsIStreamCipher.idl \ nsIKeyModule.idl \ + nsIDataSignatureVerifier.idl \ $(NULL) ifdef MOZ_XUL diff --git a/mozilla/security/manager/ssl/public/nsIDataSignatureVerifier.idl b/mozilla/security/manager/ssl/public/nsIDataSignatureVerifier.idl new file mode 100644 index 00000000000..27f80877ed1 --- /dev/null +++ b/mozilla/security/manager/ssl/public/nsIDataSignatureVerifier.idl @@ -0,0 +1,58 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the mozilla.org code. + * + * The Initial Developer of the Original Code is Ben Goodger. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Dave Townsend + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "nsISupports.idl" + +/** + * An interface for verifying that a given string of data was signed by the + * private key matching the given public key. + */ +[scriptable, uuid(0a84b3d5-6ba9-432d-89da-4fbd0b0f2aec)] +interface nsIDataSignatureVerifier : nsISupports +{ + /** + * Verifies that the data matches the data that was used to generate the + * signature. + * + * @param aData The data to be tested. + * @param aSignature The signature of the data, base64 encoded. + * @param aPublicKey The public part of the key used for signing, DER encoded + * then base64 encoded. + * @returns true if the signature matches the data, false if not. + */ + boolean verifyData(in ACString aData, in ACString aSignature, in ACString aPublicKey); +}; diff --git a/mozilla/security/manager/ssl/src/Makefile.in b/mozilla/security/manager/ssl/src/Makefile.in index 9fc4691b5c9..fd15429f088 100644 --- a/mozilla/security/manager/ssl/src/Makefile.in +++ b/mozilla/security/manager/ssl/src/Makefile.in @@ -96,7 +96,8 @@ CPPSRCS = \ nsStreamCipher.cpp \ nsKeyModule.cpp \ nsIdentityChecking.cpp \ - $(NULL) + nsDataSignatureVerifier.cpp \ + $(NULL) ifdef MOZ_XUL CPPSRCS += nsCertTree.cpp diff --git a/mozilla/security/manager/ssl/src/nsDataSignatureVerifier.cpp b/mozilla/security/manager/ssl/src/nsDataSignatureVerifier.cpp new file mode 100644 index 00000000000..e8188b9c56b --- /dev/null +++ b/mozilla/security/manager/ssl/src/nsDataSignatureVerifier.cpp @@ -0,0 +1,134 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * Contributor(s): + * Dave Townsend + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsDataSignatureVerifier.h" +#include "nsCOMPtr.h" +#include "nsString.h" + +#include "seccomon.h" +#include "nssb64.h" +#include "certt.h" +#include "keyhi.h" +#include "cryptohi.h" + +SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) + +NS_IMPL_ISUPPORTS1(nsDataSignatureVerifier, nsIDataSignatureVerifier) + +const SEC_ASN1Template CERT_SignatureDataTemplate[] = +{ + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CERTSignedData) }, + { SEC_ASN1_INLINE | SEC_ASN1_XTRN, + offsetof(CERTSignedData,signatureAlgorithm), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate), }, + { SEC_ASN1_BIT_STRING, + offsetof(CERTSignedData,signature), }, + { 0, } +}; + +NS_IMETHODIMP +nsDataSignatureVerifier::VerifyData(const nsACString & aData, + const nsACString & aSignature, + const nsACString & aPublicKey, + PRBool *_retval) +{ + // Allocate an arena to handle the majority of the allocations + PRArenaPool *arena; + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!arena) + return NS_ERROR_OUT_OF_MEMORY; + + // Base 64 decode the key + SECItem keyItem; + PORT_Memset(&keyItem, 0, sizeof(SECItem)); + if (!NSSBase64_DecodeBuffer(arena, &keyItem, + nsPromiseFlatCString(aPublicKey).get(), + aPublicKey.Length())) { + PORT_FreeArena(arena, PR_FALSE); + return NS_ERROR_FAILURE; + } + + // Extract the public key from the data + CERTSubjectPublicKeyInfo *pki = SECKEY_DecodeDERSubjectPublicKeyInfo(&keyItem); + if (!pki) { + PORT_FreeArena(arena, PR_FALSE); + return NS_ERROR_FAILURE; + } + SECKEYPublicKey *publicKey = SECKEY_ExtractPublicKey(pki); + SECKEY_DestroySubjectPublicKeyInfo(pki); + pki = nsnull; + + if (!publicKey) { + PORT_FreeArena(arena, PR_FALSE); + return NS_ERROR_FAILURE; + } + + // Base 64 decode the signature + SECItem signatureItem; + PORT_Memset(&signatureItem, 0, sizeof(SECItem)); + if (!NSSBase64_DecodeBuffer(arena, &signatureItem, + nsPromiseFlatCString(aSignature).get(), + aSignature.Length())) { + SECKEY_DestroyPublicKey(publicKey); + PORT_FreeArena(arena, PR_FALSE); + return NS_ERROR_FAILURE; + } + + // Decode the signature and algorithm + CERTSignedData sigData; + PORT_Memset(&sigData, 0, sizeof(CERTSignedData)); + SECStatus ss = SEC_QuickDERDecodeItem(arena, &sigData, + CERT_SignatureDataTemplate, + &signatureItem); + if (ss != SECSuccess) { + SECKEY_DestroyPublicKey(publicKey); + PORT_FreeArena(arena, PR_FALSE); + return NS_ERROR_FAILURE; + } + + // Perform the final verification + DER_ConvertBitString(&(sigData.signature)); + ss = VFY_VerifyDataWithAlgorithmID((const unsigned char*)nsPromiseFlatCString(aData).get(), + aData.Length(), publicKey, + &(sigData.signature), + &(sigData.signatureAlgorithm), + NULL, NULL); + + // Clean up remaining objects + SECKEY_DestroyPublicKey(publicKey); + PORT_FreeArena(arena, PR_FALSE); + + *_retval = (ss == SECSuccess); + + return NS_OK; +} diff --git a/mozilla/security/manager/ssl/src/nsDataSignatureVerifier.h b/mozilla/security/manager/ssl/src/nsDataSignatureVerifier.h new file mode 100644 index 00000000000..f9fa4f0272e --- /dev/null +++ b/mozilla/security/manager/ssl/src/nsDataSignatureVerifier.h @@ -0,0 +1,63 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * Contributor(s): + * Dave Townsend + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _NS_DATASIGNATUREVERIFIER_H_ +#define _NS_DATASIGNATUREVERIFIER_H_ + +#include "nsIDataSignatureVerifier.h" + +#include "keythi.h" + +// 296d76aa-275b-4f3c-af8a-30a4026c18fc +#define NS_DATASIGNATUREVERIFIER_CID \ + { 0x296d76aa, 0x275b, 0x4f3c, \ + { 0xaf, 0x8a, 0x30, 0xa4, 0x02, 0x6c, 0x18, 0xfc } } +#define NS_DATASIGNATUREVERIFIER_CONTRACTID \ + "@mozilla.org/security/datasignatureverifier;1" + +class nsDataSignatureVerifier : public nsIDataSignatureVerifier +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIDATASIGNATUREVERIFIER + + nsDataSignatureVerifier() + { + } + +private: + ~nsDataSignatureVerifier() + { + } +}; + +#endif // _NS_DATASIGNATUREVERIFIER_H_ diff --git a/mozilla/security/manager/ssl/src/nsNSSModule.cpp b/mozilla/security/manager/ssl/src/nsNSSModule.cpp index fcf44340134..5cd50ee004f 100644 --- a/mozilla/security/manager/ssl/src/nsNSSModule.cpp +++ b/mozilla/security/manager/ssl/src/nsNSSModule.cpp @@ -71,6 +71,7 @@ #include "nsNTLMAuthModule.h" #include "nsStreamCipher.h" #include "nsKeyModule.h" +#include "nsDataSignatureVerifier.h" // We must ensure that the nsNSSComponent has been loaded before // creating any other components. @@ -190,6 +191,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsCryptoHash) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsStreamCipher) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsKeyObject) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsKeyObjectFactory) +NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsDataSignatureVerifier) static NS_METHOD RegisterPSMContentListeners( nsIComponentManager *aCompMgr, @@ -445,6 +447,13 @@ static const nsModuleComponentInfo components[] = NS_KEYMODULEOBJECTFACTORY_CID, NS_KEYMODULEOBJECTFACTORY_CONTRACTID, nsKeyObjectFactoryConstructor + }, + + { + "Signature Verifier", + NS_DATASIGNATUREVERIFIER_CID, + NS_DATASIGNATUREVERIFIER_CONTRACTID, + nsDataSignatureVerifierConstructor } }; diff --git a/mozilla/security/manager/ssl/tests/test_datasignatureverifier.js b/mozilla/security/manager/ssl/tests/test_datasignatureverifier.js new file mode 100644 index 00000000000..ff3d5476e37 --- /dev/null +++ b/mozilla/security/manager/ssl/tests/test_datasignatureverifier.js @@ -0,0 +1,195 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; +const DSV = Ci.nsIDataSignatureVerifier; + +var keys = [ +// RSA key +"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj" + +"Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD" + +"NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf" + +"awB/zH4KaPiY3vnrzQIDAQAB", + +// RSA key +"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHe69VsjNCwnGF9YGZLgnobp3D" + +"c1KgWzpbT+f12vVKkV3YBpA9KMVMy6wpxlDjvLJjfp/0HvaH7aaz/7kgxZw70Y60" + +"LaJtkAcl1ZVAxS2lQKRTAzZ0RhoTSI1xVqGTjiQakgVdUeghtnqqwp5o1inZv3Qh" + +"nUOMNPyAV8zGt+ZQHQIDAQAB", + +// Invalid key data ("foobar" base 64 encoded) +"Zm9vYmFy" +]; + +var data = [ +"Test data for data signature verifier", +"The quick brown fox jumps over the lazy dog..." +]; + +var signatures = [ +// Key 0, Data 0, MD2 hash algorithm +"MIGTMA0GCSqGSIb3DQEBAgUAA4GBALe3hO76UCpI8b1/oJUCIPmC6AbnMAMlAqo7" + +"pc3TaWmU9wISWmXSrwNmr/QQNjWDn4nzQn8/K/Ac+tszaXib6fVLKA1a6e+/E0qE" + +"OIKFwUiDWCkGDgxM8aYiTgoSZub/5rokgse+ivuCRSVTv9mSxRzKwj+Cvp1EjKCT" + +"iIl3nnTh", + +// Key 0, Data 0, MD5 hash algorithm +"MIGTMA0GCSqGSIb3DQEBBAUAA4GBAGGb2QkA8LcA+QZj1SoVFmMpVTd9P5Ac0Rjb" + +"ldouMmngztMV/dxymVKCpknqelhsxTQ/zaqGZ4KKzcIffJa9jXi5XUD8XzDIKcFE" + +"dQvti8oUNDPb6l1ybETI8LKh2ywyBCSZ/Q5BwUeS9nfx+4cAnu9YZf29SGljit+Y" + +"XLPKZ+of", + +// Key 0, Data 0, SHA1 hash algorithm +"MIGTMA0GCSqGSIb3DQEBBQUAA4GBAHcl6tqR5yjTDUJ5NiLOdIB4I6/C/rS2WW5a" + +"7MVhYYhBgaZyGaem4LLT/REloOOLwPNMcmSEpwexqMSATbl9AAoJPq/wO3l4cZpO" + +"tDkLlafsiwnqK156YvHp50zUq5Os28d6Bq/Nl2qjH1yizwlIEo0o9qo8Cq6QK3j2" + +"MdFCopgk", + +// Key 0, Data 0, SHA256 hash algorithm +"MIGTMA0GCSqGSIb3DQEBCwUAA4GBAAOtDvzWwbYK7zLUz0F3e3wmkL1YWXuD/GzQ" + +"LgwOg6VWtn9v54M9nfv/+iX+m4udzIwHZU7utYM31vtwqRC36l0QKo2VMbiLySX+" + +"uHnSK40Kk4SfBvMF1wuz6BQ8ia8uTjPPfC764dB1N7gQdgdRevLTrh2EU6+DLmSS" + +"Sm1QJm9/", + +// Key 0, Data 0, SHA384 hash algorithm +"MIGTMA0GCSqGSIb3DQEBDAUAA4GBAMWB3DskcGuGXpi3TO2Pm0g915EIvm5aOeXQ" + +"sbs0ZGOwPyzYN1kKOmEpGHMeRhcIIBcF80ZC5N6dsTxeMGkFGOqhvB/HNl7gXMqF" + +"OA8mG9vAcwfMeJlY4H5WbYD8bUn72UbIuS+sURLvWVhuIFBYPHHU7KVUaGAWl0rp" + +"hCa4Dk37", + +// Key 0, Data 0, SHA512 hash algorithm +"MIGTMA0GCSqGSIb3DQEBDQUAA4GBAFkm61zH8Y0J5PA4GtOvoZA6w/SzHg5jFP11" + +"gmXki81VgKwLF7Gyj4wRBX7Q9c8cNrNeoGZb12NUUxlR+u6J6VxcosVPKrCz7Xfj" + +"LPi6+A1dNV5eH2B6tZR6wIiEatAWNIXxQZEJbj9BWefRFq6NnKhR5A/MEPnrZyoR" + +"Da3YsDV3", + +// Key 0, Data 1, MD2 hash algorithm +"MIGTMA0GCSqGSIb3DQEBAgUAA4GBAJjwosJK6jV9Bt6HhrFn7+48LRhamjWjzs7a" + +"cf5D/GTuul6aQQvQJ4Lt26KTyh3VglaQJFToH0Ik/fR1lOJS3tCPr1RRH06cKZgK" + +"haoUaGR8rmtn678wX067q7ACmKPeqmgj71pHm7O5YgN3z45iAazbUHP4erdbFUf9" + +"4rOr3L2f", + +// Key 0, Data 1, MD5 hash algorithm +"MIGTMA0GCSqGSIb3DQEBBAUAA4GBAC0EAoHWTb4CC+gw7fs5zMaZw7PWoDH1rXMD" + +"dKoMBDmAW1EXZTfUGUTv0ga3VzuPJKuHHZOFVyFDnt4qFrefzzWs17LiPpN+yVgo" + +"6vBnpXLeIp7D9n94bz56gv9NZZmy02XQVKDaRc3E4JBC7Ze7RAHuKtWuZRTUKF86" + +"VXakwW3a", + +// Key 0, Data 1, SHA1 hash algorithm +"MIGTMA0GCSqGSIb3DQEBBQUAA4GBABkClr0Ot3aXBKYIiARdwpX8etDQO/Eqjxe8" + +"pJyaqwj/P+x8j9/CbtJKJJTxvYmV9AhdgLPgoWjcTkfvqKdb1vpKKbV30QC/TEnu" + +"ON+66MJgkwrZw6NCDyBRgMTjf4FWR75Ot1DLuu3+7uCswKCJe8la0HMm/AcqUzu1" + +"SKOPMseI", + +// Key 0, Data 1, SHA256 hash algorithm +"MIGTMA0GCSqGSIb3DQEBCwUAA4GBAE2cIr6Uzo7RISkGgCA5m4K8s9+0iHwzr2u/" + +"3ICUrTPe4RY2g9RLd6qkwaHD101LW5TQw71fhePIxfWHEhWtTCLS5DnGiucxfGKW" + +"47gOBJIYf0DG7o5N4lA99j2Zuj+V+yjAcLfq7Su5FwASbD30KqCue1/F03qdXUxj" + +"ciJeGo2b", + +// Key 0, Data 1, SHA384 hash algorithm +"MIGTMA0GCSqGSIb3DQEBDAUAA4GBAK+JfKJNBjw2d2iXT/pe9xMXPkLSkf+gjG2i" + +"F7B0kBvMGyOVxuvQ4TCx+NFhAUevQugDHgBMkmAieg8mApcWWFWQ+8rbdUFv/hD7" + +"fHW+QukMgcfLMquh0GtDuoM8ZKFBBvwnPGLLUh+ZMy8fEOjjH+s6bQQSpf072SSJ" + +"K+Uo8DG2", + +// Key 0, Data 1, SHA512 hash algorithm +"MIGTMA0GCSqGSIb3DQEBDQUAA4GBAEEvDpyBssG0qFfRamNwkwSjhqYRVFdIa6+E" + +"xfxdRqW/nxN5HuzFA8aajgSMXX0YFWPXV7OuVjCCJfZWhq7kQpTy96AmI/04rVdr" + +"9gc5mc2tdLl3Yk/Qd+Xq8WYcQIZ5Ewyo7sr8eKtVhtEM8OtPR54FO2s1pkZwJdVf" + +"ymMzHBoE", + +// Key 1, Data 0, MD5 hash algorithm +"MIGTMA0GCSqGSIb3DQEBBAUAA4GBAAIzLho2i5jfJ5SPPV/u2gUuefzhjEAsUhlL" + +"Nir4FKhNzB2DZNbME9DtgNvdmZd00IjydYlaJ0dnLiMigXIaRJsyncYazULZdY6i" + +"i7oP6llbXbszSTbHGolr5kQ+6cZPBBATOkJ+wekDdlvh5cZ+B0Lux4LevUDlGWAy" + +"uR7bqrc5", + +// Key 1, Data 0, SHA512 hash algorithm +"MIGTMA0GCSqGSIb3DQEBDQUAA4GBABsjF8K/SIaY3KTeIGpPEwl1+ZXLKBaHxlRT" + +"b37PhorSfqW1KFjquCEASUUeFwCQ14uUIBaRQV2haRGA0dRpuWr4zrWZMcDKOsmX" + +"r5XRvcti9/lNqoIID/Mq0tKtS6aVFZpoHIrwbXpV4hV+BRGhaPxV3RBzEIzM7bWJ" + +"tN3JY9+1", + +// Key 1, Data 1, MD5 hash algorithm +"MIGTMA0GCSqGSIb3DQEBBAUAA4GBAIAxRPXDAT2LBcOo7yTNr5uIZbPW9rkSX0Ba" + +"h4sq6YRcxlnohaE2VO0CLGXFNwaBihhkkp+2dA76EvbMo/+O9XTWwroqtWWwvmxs" + +"tWK6HvwYKnGFKOOZMOjNjmXjk446UVvxYCbU+NPM1LZTewT1/UpPWWRowF/lwX7m" + +"SnT8d2ds", + +// Key 1, Data 1, SHA512 hash algorithm +"MIGTMA0GCSqGSIb3DQEBDQUAA4GBAF0+XYD/r0Annz1GJ24GTkAlWY/OixCSV6Ix" + +"OMM7P2d/jgOP+ICKIpxqaSE0CbkLiegUiidIOWvFqDxQJWlAAukDUWISGFfJMFxX" + +"3jzJ0bBfeNY/1Qo8jMQopcNco/NlNgoSKAUOBtk31aFgNoVC3kWUk6pO97KEiJ+e" + +"bQp9Z2/M", + +// Invalid signature data ("foobar" base 64 encoded) +"Zm9vYmFy" +]; + +var tests = [ +// Data Signature Key Expected Throws +// Pass cases + [0, 0, 0, true, false], //0 + [0, 1, 0, true, false], //1 + [0, 2, 0, true, false], //2 + [0, 3, 0, true, false], //3 + [0, 4, 0, true, false], //4 + [0, 5, 0, true, false], //5 + [1, 6, 0, true, false], //6 + [1, 7, 0, true, false], //7 + [1, 8, 0, true, false], //8 + [1, 9, 0, true, false], //9 + [1, 10, 0, true, false], //10 + [1, 11, 0, true, false], //11 + [0, 12, 1, true, false], //12 + [0, 13, 1, true, false], //13 + [1, 14, 1, true, false], //14 + [1, 15, 1, true, false], //15 +// Incorrect data cases + [1, 0, 0, false, false], //16 + [1, 1, 0, false, false], //17 + [1, 2, 0, false, false], //18 + [1, 3, 0, false, false], //19 + [1, 4, 0, false, false], //20 + [1, 5, 0, false, false], //21 + [0, 6, 0, false, false], //22 + [0, 7, 0, false, false], //23 + [0, 8, 0, false, false], //24 + [0, 9, 0, false, false], //25 + [0, 10, 0, false, false], //26 + [0, 11, 0, false, false], //27 +// Incorrect key cases + [0, 1, 1, false, false], //28 + [0, 5, 1, false, false], //29 + [1, 7, 1, false, false], //30 + [1, 11, 1, false, false], //31 + [0, 12, 0, false, false], //32 + [0, 13, 0, false, false], //33 + [1, 14, 0, false, false], //34 + [1, 15, 0, false, false], //35 +// Invalid data cases + [0, 0, 2, false, true], //36 + [0, 1, 2, false, true], //37 + [0, 16, 0, false, true], //38 + [1, 16, 0, false, true], //39 +]; + +function run_test() { + var verifier = Cc["@mozilla.org/security/datasignatureverifier;1"]. + createInstance(Ci.nsIDataSignatureVerifier); + + for (var t = 0; t < tests.length; t++) { + try { + var result = verifier.verifyData(data[tests[t][0]], + signatures[tests[t][1]], + keys[tests[t][2]]); + if (tests[t][4]) + do_throw("Test " + t + " didn't throw"); + if (result != tests[t][3]) + do_throw("Test " + t + " was " + result + " but should have been " + tests[t][3]); + } + catch (e) { + if (!tests[t][4]) + do_throw("Test " + t + " threw " + e); + } + } +}