LibreOffice Module onlineupdate (master) 1
cryptox.c
Go to the documentation of this file.
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/. */
4
5#ifdef _WIN32
6#ifndef WIN32_LEAN_AND_MEAN
7#define WIN32_LEAN_AND_MEAN
8#endif
9#endif
10
11#include <stdlib.h>
12#include "cryptox.h"
13
14#ifdef _WIN32
15#pragma warning(push)
16#pragma warning(disable: 4204)
17#endif
18
19#if defined(MAR_NSS)
20
30NSS_LoadPublicKey(const unsigned char *certData, unsigned int certDataSize,
31 SECKEYPublicKey **publicKey)
32{
33 CERTCertificate * cert;
34 SECItem certDataItem = { siBuffer, (unsigned char*) certData, certDataSize };
35
36 if (!certData || !publicKey) {
37 return CryptoX_Error;
38 }
39
40 cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &certDataItem, NULL,
41 PR_FALSE, PR_TRUE);
42 /* Get the cert and embedded public key out of the database */
43 if (!cert) {
44 return CryptoX_Error;
45 }
46 *publicKey = CERT_ExtractPublicKey(cert);
47 CERT_DestroyCertificate(cert);
48
49 if (!*publicKey) {
50 return CryptoX_Error;
51 }
52 return CryptoX_Success;
53}
54
56NSS_VerifyBegin(VFYContext **ctx,
57 SECKEYPublicKey * const *publicKey)
58{
59 SECStatus status;
60 if (!ctx || !publicKey || !*publicKey) {
61 return CryptoX_Error;
62 }
63
64 /* Check that the key length is large enough for our requirements */
65 if ((SECKEY_PublicKeyStrength(*publicKey) * 8) <
67 fprintf(stderr, "ERROR: Key length must be >= %d bytes\n",
69 return CryptoX_Error;
70 }
71
72 *ctx = VFY_CreateContext(*publicKey, NULL,
73 SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE, NULL);
74 if (*ctx == NULL) {
75 return CryptoX_Error;
76 }
77
78 status = VFY_Begin(*ctx);
79 return SECSuccess == status ? CryptoX_Success : CryptoX_Error;
80}
81
91NSS_VerifySignature(VFYContext * const *ctx,
92 const unsigned char *signature,
93 unsigned int signatureLen)
94{
95 SECItem signedItem;
96 SECStatus status;
97 if (!ctx || !signature || !*ctx) {
98 return CryptoX_Error;
99 }
100
101 signedItem.len = signatureLen;
102 signedItem.data = (unsigned char*)signature;
103 status = VFY_EndWithSignature(*ctx, &signedItem);
104 return SECSuccess == status ? CryptoX_Success : CryptoX_Error;
105}
106
107#elif defined(WNT)
118CryptoAPI_VerifySignature(HCRYPTHASH *hash,
119 HCRYPTKEY *pubKey,
120 const BYTE *signature,
121 DWORD signatureLen)
122{
123 DWORD i;
124 BOOL result;
125/* Windows APIs expect the bytes in the signature to be in little-endian
126 * order, but we write the signature in big-endian order. Other APIs like
127 * NSS and OpenSSL expect big-endian order.
128 */
129 BYTE *signatureReversed;
130 if (!hash || !pubKey || !signature || signatureLen < 1) {
131 return CryptoX_Error;
132 }
133
134 signatureReversed = malloc(signatureLen);
135 if (!signatureReversed) {
136 return CryptoX_Error;
137 }
138
139 for (i = 0; i < signatureLen; i++) {
140 signatureReversed[i] = signature[signatureLen - 1 - i];
141 }
142 result = CryptVerifySignature(*hash, signatureReversed,
143 signatureLen, *pubKey, NULL, 0);
144 free(signatureReversed);
146}
147
158CryptoAPI_LoadPublicKey(HCRYPTPROV provider,
159 BYTE *certData,
160 DWORD sizeOfCertData,
161 HCRYPTKEY *publicKey)
162{
163 CRYPT_DATA_BLOB blob;
164 CERT_CONTEXT *context;
165 if (!provider || !certData || !publicKey) {
166 return CryptoX_Error;
167 }
168
169 blob.cbData = sizeOfCertData;
170 blob.pbData = certData;
171 if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob,
172 CERT_QUERY_CONTENT_FLAG_CERT,
173 CERT_QUERY_FORMAT_FLAG_BINARY,
174 0, NULL, NULL, NULL,
175 NULL, NULL, (const void **)&context)) {
176 return CryptoX_Error;
177 }
178
179 if (!CryptImportPublicKeyInfo(provider,
180 PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
181 &context->pCertInfo->SubjectPublicKeyInfo,
182 publicKey)) {
183 CertFreeCertificateContext(context);
184 return CryptoX_Error;
185 }
186
187 CertFreeCertificateContext(context);
188 return CryptoX_Success;
189}
190
191/* Try to acquire context in this way:
192 * 1. Enhanced provider without creating a new key set
193 * 2. Enhanced provider with creating a new key set
194 * 3. Default provider without creating a new key set
195 * 4. Default provider without creating a new key set
196 * #2 and #4 should not be needed because of the CRYPT_VERIFYCONTEXT,
197 * but we add it just in case.
198 *
199 * @param provider Out parameter containing the provider handle.
200 * @return CryptoX_Success on success, CryptoX_Error on error.
201 */
203CryptoAPI_InitCryptoContext(HCRYPTPROV *provider)
204{
205 if (!CryptAcquireContext(provider,
206 NULL,
207 MS_ENHANCED_PROV,
208 PROV_RSA_FULL,
209 CRYPT_VERIFYCONTEXT)) {
210 if (!CryptAcquireContext(provider,
211 NULL,
212 MS_ENHANCED_PROV,
213 PROV_RSA_FULL,
214 CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) {
215 if (!CryptAcquireContext(provider,
216 NULL,
217 NULL,
218 PROV_RSA_FULL,
219 CRYPT_VERIFYCONTEXT)) {
220 if (!CryptAcquireContext(provider,
221 NULL,
222 NULL,
223 PROV_RSA_FULL,
224 CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) {
225 *provider = CryptoX_InvalidHandleValue;
226 return CryptoX_Error;
227 }
228 }
229 }
230 }
231 return CryptoX_Success;
232}
233
242CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH* hash)
243{
244 BOOL result;
245 if (!provider || !hash) {
246 return CryptoX_Error;
247 }
248
249 *hash = (HCRYPTHASH)NULL;
250 result = CryptCreateHash(provider, CALG_SHA1,
251 0, 0, hash);
253}
254
264CryptoAPI_VerifyUpdate(HCRYPTHASH* hash, BYTE *buf, DWORD len)
265{
266 BOOL result;
267 if (!hash || !buf) {
268 return CryptoX_Error;
269 }
270
271 result = CryptHashData(*hash, buf, len, 0);
273}
274
275#ifdef _WIN32
276#pragma warning(pop)
277#endif
278
279#endif
280
281
282
#define CryptoX_InvalidHandleValue
Definition: cryptox.h:154
#define CryptoX_Error
Definition: cryptox.h:12
#define CryptoX_Success
Definition: cryptox.h:11
#define XP_MIN_SIGNATURE_LEN_IN_BYTES
Definition: cryptox.h:8
#define CryptoX_Result
Definition: cryptox.h:10
int i
ctx
#define CERT_NewTempCertificate
const wchar_t *typedef BOOL
Any result
unsigned char BYTE