1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is mozilla.org code.
17 * Dave Townsend <dtownsend@oxymoronical.com>
19 * Alternatively, the contents of this file may be used under the terms of
20 * either the GNU General Public License Version 2 or later (the "GPL"), or
21 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
22 * in which case the provisions of the GPL or the LGPL are applicable instead
23 * of those above. If you wish to allow use of your version of this file only
24 * under the terms of either the GPL or the LGPL, and not to allow others to
25 * use your version of this file under the terms of the MPL, indicate your
26 * decision by deleting the provisions above and replace them with the notice
27 * and other provisions required by the GPL or the LGPL. If you do not delete
28 * the provisions above, a recipient may use your version of this file under
29 * the terms of any one of the MPL, the GPL or the LGPL.
31 * ***** END LICENSE BLOCK ***** */
33 #include "nsDataSignatureVerifier.h"
43 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate
)
45 NS_IMPL_ISUPPORTS1(nsDataSignatureVerifier
, nsIDataSignatureVerifier
)
47 const SEC_ASN1Template CERT_SignatureDataTemplate
[] =
50 0, NULL
, sizeof(CERTSignedData
) },
51 { SEC_ASN1_INLINE
| SEC_ASN1_XTRN
,
52 offsetof(CERTSignedData
,signatureAlgorithm
),
53 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate
), },
54 { SEC_ASN1_BIT_STRING
,
55 offsetof(CERTSignedData
,signature
), },
60 nsDataSignatureVerifier::VerifyData(const nsACString
& aData
,
61 const nsACString
& aSignature
,
62 const nsACString
& aPublicKey
,
65 // Allocate an arena to handle the majority of the allocations
67 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
69 return NS_ERROR_OUT_OF_MEMORY
;
71 // Base 64 decode the key
73 PORT_Memset(&keyItem
, 0, sizeof(SECItem
));
74 if (!NSSBase64_DecodeBuffer(arena
, &keyItem
,
75 nsPromiseFlatCString(aPublicKey
).get(),
76 aPublicKey
.Length())) {
77 PORT_FreeArena(arena
, PR_FALSE
);
78 return NS_ERROR_FAILURE
;
81 // Extract the public key from the data
82 CERTSubjectPublicKeyInfo
*pki
= SECKEY_DecodeDERSubjectPublicKeyInfo(&keyItem
);
84 PORT_FreeArena(arena
, PR_FALSE
);
85 return NS_ERROR_FAILURE
;
87 SECKEYPublicKey
*publicKey
= SECKEY_ExtractPublicKey(pki
);
88 SECKEY_DestroySubjectPublicKeyInfo(pki
);
92 PORT_FreeArena(arena
, PR_FALSE
);
93 return NS_ERROR_FAILURE
;
96 // Base 64 decode the signature
97 SECItem signatureItem
;
98 PORT_Memset(&signatureItem
, 0, sizeof(SECItem
));
99 if (!NSSBase64_DecodeBuffer(arena
, &signatureItem
,
100 nsPromiseFlatCString(aSignature
).get(),
101 aSignature
.Length())) {
102 SECKEY_DestroyPublicKey(publicKey
);
103 PORT_FreeArena(arena
, PR_FALSE
);
104 return NS_ERROR_FAILURE
;
107 // Decode the signature and algorithm
108 CERTSignedData sigData
;
109 PORT_Memset(&sigData
, 0, sizeof(CERTSignedData
));
110 SECStatus ss
= SEC_QuickDERDecodeItem(arena
, &sigData
,
111 CERT_SignatureDataTemplate
,
113 if (ss
!= SECSuccess
) {
114 SECKEY_DestroyPublicKey(publicKey
);
115 PORT_FreeArena(arena
, PR_FALSE
);
116 return NS_ERROR_FAILURE
;
119 // Perform the final verification
120 DER_ConvertBitString(&(sigData
.signature
));
121 ss
= VFY_VerifyDataWithAlgorithmID((const unsigned char*)nsPromiseFlatCString(aData
).get(),
122 aData
.Length(), publicKey
,
123 &(sigData
.signature
),
124 &(sigData
.signatureAlgorithm
),
127 // Clean up remaining objects
128 SECKEY_DestroyPublicKey(publicKey
);
129 PORT_FreeArena(arena
, PR_FALSE
);
131 *_retval
= (ss
== SECSuccess
);