зеркало из https://github.com/mozilla/pjs.git
PCKS7 implementation for signed JS. Bug# 82227 r=mstoltz@netscape.com,sr=blizzard@mozilla.org,a=blizzard@mozilla.org
This commit is contained in:
Родитель
cb69c77296
Коммит
a86397a93a
|
@ -24,7 +24,14 @@
|
|||
/* An interface for calculating secure hashes and verifying signatures*/
|
||||
#include "nsIPrincipal.idl"
|
||||
|
||||
//interface nsIX509Cert;
|
||||
|
||||
%{C++
|
||||
struct HASHContextStr;
|
||||
%}
|
||||
|
||||
[ptr] native UnsignedCharPtr(unsigned char);
|
||||
[ptr] native HASHContextPtr(HASHContextStr);
|
||||
|
||||
[uuid(7bdbdb36-1dd2-11b2-a44f-e303037f214d)]
|
||||
interface nsISignatureVerifier : nsISupports
|
||||
|
@ -43,19 +50,16 @@ interface nsISignatureVerifier : nsISupports
|
|||
const unsigned long MAX_HASH_LENGTH = SHA1_LENGTH;
|
||||
|
||||
/* Secure Hashing functions */
|
||||
void hashBegin(in unsigned long alg, out unsigned long id);
|
||||
void hashUpdate(in unsigned long id, in string buf, in unsigned long buflen);
|
||||
[noscript] void hashEnd(in unsigned long id, out UnsignedCharPtr hash,
|
||||
HASHContextPtr hashBegin(in unsigned long alg);
|
||||
void hashUpdate(in HASHContextPtr id, in string buf, in unsigned long buflen);
|
||||
[noscript] void hashEnd(in HASHContextPtr id, out UnsignedCharPtr hash,
|
||||
out unsigned long hashlen, in unsigned long maxLen);
|
||||
|
||||
/* Signature Verification functions */
|
||||
nsIPrincipal createPrincipalFromSignature(in string aSignature,
|
||||
in unsigned long aSignatureLen);
|
||||
nsIPrincipal verifySignature(in string aSignature,
|
||||
in unsigned long aSignatureLen,
|
||||
in string plaintext,
|
||||
in unsigned long plaintextLen,
|
||||
out long errorCode);
|
||||
in unsigned long aSignatureLen,
|
||||
in string plaintext,
|
||||
in unsigned long plaintextLen,
|
||||
out long errorCode);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -47,12 +47,15 @@
|
|||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsProxiedService.h"
|
||||
#include "nsICertificatePrincipal.h"
|
||||
|
||||
#include "nss.h"
|
||||
#include "pk11func.h"
|
||||
#include "ssl.h"
|
||||
#include "sslproto.h"
|
||||
#include "secmod.h"
|
||||
#include "sechash.h"
|
||||
#include "secmime.h"
|
||||
#include "ocsp.h"
|
||||
extern "C" {
|
||||
#include "pkcs11.h"
|
||||
|
@ -527,32 +530,31 @@ nsNSSComponent::DisplaySecurityAdvisor()
|
|||
// Functions Implementing nsISignatureVerifier
|
||||
//---------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::HashBegin(PRUint32 alg, PRUint32* id)
|
||||
nsNSSComponent::HashBegin(PRUint32 alg, HASHContext** id)
|
||||
{
|
||||
return NS_OK; /* not sure what the implications of this are */
|
||||
*id = HASH_Create((HASH_HashType)alg);
|
||||
if (*id) {
|
||||
HASH_Begin(*id);
|
||||
return NS_OK;
|
||||
} else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::HashUpdate(PRUint32 id, const char* buf, PRUint32 buflen)
|
||||
nsNSSComponent::HashUpdate(HASHContext* ctx, const char* buf, PRUint32 buflen)
|
||||
{
|
||||
return NS_OK; /* not sure what the implications of this are */
|
||||
HASH_Update(ctx, (const unsigned char*)buf, buflen);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::HashEnd(PRUint32 id, unsigned char** hash,
|
||||
nsNSSComponent::HashEnd(HASHContext* ctx, unsigned char** hash,
|
||||
PRUint32* hashLen, PRUint32 maxLen)
|
||||
{
|
||||
return NS_OK; /* not sure what the implications of this are */
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::CreatePrincipalFromSignature(const char* aRSABuf,
|
||||
PRUint32 aRSABufLen,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
PRInt32 errorCode;
|
||||
return VerifySignature(aRSABuf, aRSABufLen, nsnull, 0, &errorCode,
|
||||
aPrincipal);
|
||||
HASH_End(ctx, *hash, hashLen, maxLen);
|
||||
HASH_Destroy(ctx);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -564,12 +566,129 @@ nsNSSComponent::GetPassword(char **aRet)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* Callback functions for decoder. For now, use empty/default functions. */
|
||||
static void ContentCallback(void *arg,
|
||||
const char *buf,
|
||||
unsigned long len)
|
||||
{
|
||||
}
|
||||
|
||||
static PK11SymKey * GetDecryptKeyCallback(void *arg,
|
||||
SECAlgorithmID *algid)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
static PRBool DecryptionAllowedCallback(SECAlgorithmID *algid,
|
||||
PK11SymKey *bulkkey)
|
||||
{
|
||||
return SECMIME_DecryptionAllowed(algid, bulkkey);
|
||||
}
|
||||
|
||||
static SECItem * GetPasswordKeyCallback(void *arg,
|
||||
SECKEYKeyDBHandle *handle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSComponent::VerifySignature(const char* aRSABuf, PRUint32 aRSABufLen,
|
||||
const char* aPlaintext, PRUint32 aPlaintextLen,
|
||||
PRInt32* aErrorCode,
|
||||
nsIPrincipal** aPrincipal)
|
||||
{
|
||||
SEC_PKCS7DecoderContext * p7_ctxt = nsnull;
|
||||
SEC_PKCS7ContentInfo * p7_info = nsnull;
|
||||
unsigned char hash[SHA1_LENGTH];
|
||||
PRBool rv;
|
||||
|
||||
if (!aPrincipal || !aErrorCode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
*aErrorCode = 0;
|
||||
*aPrincipal = nsnull;
|
||||
|
||||
p7_ctxt = SEC_PKCS7DecoderStart(ContentCallback,
|
||||
nsnull,
|
||||
GetPasswordKeyCallback,
|
||||
nsnull,
|
||||
GetDecryptKeyCallback,
|
||||
nsnull,
|
||||
DecryptionAllowedCallback);
|
||||
if (!p7_ctxt) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (SEC_PKCS7DecoderUpdate(p7_ctxt,aRSABuf, aRSABufLen) != SECSuccess) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
p7_info = SEC_PKCS7DecoderFinish(p7_ctxt);
|
||||
if (!p7_info) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//-- If a plaintext was provided, hash it.
|
||||
SECItem digest;
|
||||
digest.data = nsnull;
|
||||
digest.len = 0;
|
||||
|
||||
if (aPlaintext) {
|
||||
HASHContext* hash_ctxt;
|
||||
PRUint32 hashLen = 0;
|
||||
|
||||
hash_ctxt = HASH_Create(HASH_AlgSHA1);
|
||||
HASH_Begin(hash_ctxt);
|
||||
HASH_Update(hash_ctxt,(const unsigned char*)aPlaintext, aPlaintextLen);
|
||||
HASH_End(hash_ctxt, hash, &hashLen, SHA1_LENGTH);
|
||||
HASH_Destroy(hash_ctxt);
|
||||
|
||||
digest.data = hash;
|
||||
digest.len = SHA1_LENGTH;
|
||||
}
|
||||
|
||||
//-- Verify signature
|
||||
rv = SEC_PKCS7VerifyDetachedSignature(p7_info, certUsageObjectSigner, &digest, HASH_AlgSHA1, PR_TRUE);
|
||||
if (rv != PR_SUCCESS) {
|
||||
*aErrorCode = PR_GetError();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the signing cert //
|
||||
CERTCertificate *cert = p7_info->content.signedData->signerInfos[0]->cert;
|
||||
if (cert) {
|
||||
nsresult rv2;
|
||||
nsCOMPtr<nsIX509Cert> pCert = new nsNSSCertificate(cert);
|
||||
if (!mScriptSecurityManager) {
|
||||
mScriptSecurityManager =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv2);
|
||||
if (NS_FAILED(rv2)) return rv2;
|
||||
}
|
||||
//-- Create a certificate principal with id and organization data
|
||||
PRUnichar* fingerprint;
|
||||
rv2 = pCert->GetSha1Fingerprint(&fingerprint);
|
||||
nsCAutoString fingerprintStr;
|
||||
fingerprintStr.AssignWithConversion(fingerprint);
|
||||
PR_FREEIF(fingerprint);
|
||||
if (NS_FAILED(rv2)) return rv2;
|
||||
rv2 = mScriptSecurityManager->GetCertificatePrincipal(fingerprintStr, aPrincipal);
|
||||
if (NS_FAILED(rv2) || !*aPrincipal) return rv2;
|
||||
|
||||
nsCOMPtr<nsICertificatePrincipal> certPrincipal = do_QueryInterface(*aPrincipal, &rv2);
|
||||
if (NS_FAILED(rv2)) return rv2;
|
||||
PRUnichar* orgName;
|
||||
rv2 = pCert->GetOrganization(&orgName);
|
||||
if (NS_FAILED(rv2)) return rv2;
|
||||
nsCAutoString orgNameStr;
|
||||
orgNameStr.AssignWithConversion(orgName);
|
||||
PR_FREEIF(orgName);
|
||||
rv2 = certPrincipal->SetCommonName(orgNameStr);
|
||||
if (NS_FAILED(rv2)) return rv2;
|
||||
}
|
||||
|
||||
if (p7_info) {
|
||||
SEC_PKCS7DestroyContentInfo(p7_info);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "nsIPref.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
||||
#include "nsNSSHelper.h"
|
||||
|
||||
|
@ -112,6 +113,7 @@ private:
|
|||
static int PR_CALLBACK PrefChangedCallback(const char* aPrefName, void* data);
|
||||
void PrefChanged(const char* aPrefName);
|
||||
|
||||
nsCOMPtr<nsIScriptSecurityManager> mScriptSecurityManager;
|
||||
nsCOMPtr<nsIStringBundle> mPIPNSSBundle;
|
||||
nsCOMPtr<nsIURIContentListener> mPSMContentListener;
|
||||
nsCOMPtr<nsIPref> mPref;
|
||||
|
|
Загрузка…
Ссылка в новой задаче