1 /*
2  * XML Security Library (http://www.aleksey.com/xmlsec).
3  *
4  *
5  * This is free software; see Copyright file in the source
6  * distribution for preciese wording.
7  *
8  * Copyright (C) 2003 Cordys R&D BV, All rights reserved.
9  * Copyright (C) 2003-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved.
10  */
11 /**
12  * SECTION:certkeys
13  * @Short_description: Certificate keys support functions for Microsoft Crypto API.
14  * @Stability: Stable
15  *
16  */
17 
18 #include "globals.h"
19 
20 #include <string.h>
21 
22 #include <windows.h>
23 #include <wincrypt.h>
24 
25 #ifndef XMLSEC_NO_GOST
26 #include "csp_oid.h"
27 #include "csp_calg.h"
28 #endif
29 
30 #include <xmlsec/xmlsec.h>
31 #include <xmlsec/xmltree.h>
32 #include <xmlsec/keys.h>
33 #include <xmlsec/keyinfo.h>
34 #include <xmlsec/transforms.h>
35 #include <xmlsec/errors.h>
36 #include <xmlsec/bn.h>
37 
38 #include <xmlsec/mscrypto/certkeys.h>
39 #include <xmlsec/mscrypto/crypto.h>
40 #include <xmlsec/mscrypto/x509.h>
41 #include "private.h"
42 
43 // GOST CSP don't support keys duplicating, so we use NT4 analogs for these...
44 #ifndef XMLSEC_NO_GOST
45 #ifndef XMLSEC_MSCRYPTO_NT4
46 #define XMLSEC_MSCRYPTO_NT4
47 #endif
48 #endif
49 
50 
51 /**************************************************************************
52  *
53  * Internal MSCrypto PCCERT_CONTEXT key CTX
54  *
55  *************************************************************************/
56 typedef struct _xmlSecMSCryptoKeyDataCtx xmlSecMSCryptoKeyDataCtx,
57                                                 *xmlSecMSCryptoKeyDataCtxPtr;
58 
59 #ifdef XMLSEC_MSCRYPTO_NT4
60 /*-
61  * A wrapper of HCRYPTKEY, a reference counter is introduced, the function is
62  * the same as CryptDuplicateKey. Because the CryptDuplicateKey is not support
63  * by WINNT 4.0, the wrapper will enable the library work on WINNT 4.0
64  */
65 struct _mscrypt_key {
66         HCRYPTKEY hKey ;
67         volatile LONG refcnt ;
68 } ;
69 
70 /*-
71  * A wrapper of HCRYPTPROV, a reference counter is introduced, the function is
72  * the same as CryptContextAddRef. Because the CryptContextAddRef is not support
73  * by WINNT 4.0, the wrapper will enable the library work on WINNT 4.0
74  */
75 struct _mscrypt_prov {
76         HCRYPTPROV hProv ;
77     BOOL fCallerFreeProv ;
78         volatile LONG refcnt ;
79 } ;
80 #endif /* XMLSEC_MSCRYPTO_NT4 */
81 
82 /*
83  * Since MSCrypto does not provide direct handles to private keys, we support
84  * only private keys linked to a certificate context. The certificate context
85  * also provides the public key. Only when no certificate context is used, and
86  * a public key from xml document is provided, we need HCRYPTKEY.... The focus
87  * now is however directed to certificates.  Wouter
88  */
89 struct _xmlSecMSCryptoKeyDataCtx {
90 #ifndef XMLSEC_MSCRYPTO_NT4
91     HCRYPTPROV                          hProv;
92     BOOL                                fCallerFreeProv;
93     HCRYPTKEY                           hKey;
94 #else /* XMLSEC_MSCRYPTO_NT4 */
95     struct _mscrypt_prov*               p_prov ;
96     struct _mscrypt_key*                p_key ;
97 #endif /* XMLSEC_MSCRYPTO_NT4 */
98     PCCERT_CONTEXT                      pCert;
99     const xmlSecMSCryptoProviderInfo  * providers;
100     DWORD                               dwKeySpec;
101     xmlSecKeyDataType   type;
102 };
103 
104 #ifndef XMLSEC_MSCRYPTO_NT4
105 
106 /******************************** Provider *****************************************/
107 #define xmlSecMSCryptoKeyDataCtxGetProvider(ctx)            (ctx)->hProv
108 
109 static int
xmlSecMSCryptoKeyDataCtxCreateProvider(xmlSecMSCryptoKeyDataCtxPtr ctx)110 xmlSecMSCryptoKeyDataCtxCreateProvider(xmlSecMSCryptoKeyDataCtxPtr ctx) {
111     xmlSecAssert2(ctx != NULL, -1);
112 
113     ctx->hProv = 0;
114     ctx->fCallerFreeProv = FALSE;
115     return(0);
116 }
117 
118 static void
xmlSecMSCryptoKeyDataCtxDestroyProvider(xmlSecMSCryptoKeyDataCtxPtr ctx)119 xmlSecMSCryptoKeyDataCtxDestroyProvider(xmlSecMSCryptoKeyDataCtxPtr ctx) {
120     xmlSecAssert(ctx != NULL);
121 
122     if ((ctx->hProv != 0) && (ctx->fCallerFreeProv)) {
123         CryptReleaseContext(ctx->hProv, 0);
124     }
125     ctx->hProv = 0;
126     ctx->fCallerFreeProv = FALSE;
127 }
128 
129 static int
xmlSecMSCryptoKeyDataCtxSetProvider(xmlSecMSCryptoKeyDataCtxPtr ctx,HCRYPTPROV hProv,BOOL fCallerFreeProv)130 xmlSecMSCryptoKeyDataCtxSetProvider(xmlSecMSCryptoKeyDataCtxPtr ctx, HCRYPTPROV hProv, BOOL fCallerFreeProv)
131 {
132     xmlSecAssert2(ctx != NULL, -1);
133 
134     xmlSecMSCryptoKeyDataCtxDestroyProvider(ctx);
135     ctx->hProv               = hProv;
136     ctx->fCallerFreeProv = fCallerFreeProv;
137     return(0);
138 }
139 
140 static int
xmlSecMSCryptoKeyDataCtxDuplicateProvider(xmlSecMSCryptoKeyDataCtxPtr ctxDst,xmlSecMSCryptoKeyDataCtxPtr ctxSrc)141 xmlSecMSCryptoKeyDataCtxDuplicateProvider(xmlSecMSCryptoKeyDataCtxPtr ctxDst, xmlSecMSCryptoKeyDataCtxPtr ctxSrc) {
142     xmlSecAssert2(ctxDst != NULL, -1);
143     xmlSecAssert2(ctxSrc != NULL, -1);
144 
145     xmlSecMSCryptoKeyDataCtxDestroyProvider(ctxDst);
146 
147     if(ctxSrc->hProv != 0) {
148         if(!CryptContextAddRef(ctxSrc->hProv, NULL, 0)) {
149                 xmlSecMSCryptoError("CryptContextAddRef", NULL);
150             return(-1);
151         }
152 
153             ctxDst->hProv                   = ctxSrc->hProv;
154             ctxDst->fCallerFreeProv = TRUE;
155     }
156     return(0);
157 }
158 
159 
160 /******************************** Key *****************************************/
161 #define xmlSecMSCryptoKeyDataCtxGetKey(ctx)            ((ctx)->hKey)
162 
163 static int
xmlSecMSCryptoKeyDataCtxCreateKey(xmlSecMSCryptoKeyDataCtxPtr ctx)164 xmlSecMSCryptoKeyDataCtxCreateKey(xmlSecMSCryptoKeyDataCtxPtr ctx) {
165     xmlSecAssert2(ctx != NULL, -1);
166 
167     ctx->hKey = 0;
168     return(0);
169 }
170 
171 static void
xmlSecMSCryptoKeyDataCtxDestroyKey(xmlSecMSCryptoKeyDataCtxPtr ctx)172 xmlSecMSCryptoKeyDataCtxDestroyKey(xmlSecMSCryptoKeyDataCtxPtr ctx) {
173     xmlSecAssert(ctx != NULL);
174 
175     if (ctx->hKey != 0) {
176             CryptDestroyKey(ctx->hKey);
177     }
178     ctx->hKey = 0;
179 }
180 
181 static int
xmlSecMSCryptoKeyDataCtxSetKey(xmlSecMSCryptoKeyDataCtxPtr ctx,HCRYPTKEY hKey)182 xmlSecMSCryptoKeyDataCtxSetKey(xmlSecMSCryptoKeyDataCtxPtr ctx, HCRYPTKEY hKey) {
183     xmlSecAssert2(ctx != NULL, -1);
184 
185     xmlSecMSCryptoKeyDataCtxDestroyKey(ctx);
186     ctx->hKey = hKey;
187     return(0);
188 }
189 
190 static int
xmlSecMSCryptoKeyDataCtxDuplicateKey(xmlSecMSCryptoKeyDataCtxPtr ctxDst,xmlSecMSCryptoKeyDataCtxPtr ctxSrc)191 xmlSecMSCryptoKeyDataCtxDuplicateKey(xmlSecMSCryptoKeyDataCtxPtr ctxDst, xmlSecMSCryptoKeyDataCtxPtr ctxSrc) {
192     xmlSecAssert2(ctxDst != NULL, -1);
193     xmlSecAssert2(ctxSrc != NULL, -1);
194 
195     xmlSecMSCryptoKeyDataCtxDestroyKey(ctxDst);
196     if (ctxSrc->hKey != 0) {
197             if (!CryptDuplicateKey(ctxSrc->hKey, NULL, 0, &(ctxDst->hKey))) {
198                 xmlSecMSCryptoError("CryptDuplicateKey", NULL);
199                 return(-1);
200             }
201     }
202 
203     return(0);
204 }
205 
206 #else /* XMLSEC_MSCRYPTO_NT4 */
207 
208 /******************************** Provider *****************************************/
209 #define xmlSecMSCryptoKeyDataCtxGetProvider(ctx)            (((ctx)->p_prov) ? ((ctx)->p_prov->hProv) : 0)
210 
211 static int
xmlSecMSCryptoKeyDataCtxCreateProvider(xmlSecMSCryptoKeyDataCtxPtr ctx)212 xmlSecMSCryptoKeyDataCtxCreateProvider(xmlSecMSCryptoKeyDataCtxPtr ctx) {
213     xmlSecAssert2(ctx != NULL, -1);
214 
215     ctx->p_prov = (struct _mscrypt_prov*)xmlMalloc(sizeof(struct _mscrypt_prov));
216     if(ctx->p_prov == NULL) {
217         xmlSecMallocError(sizeof(struct _mscrypt_prov), NULL);
218         return(-1);
219     }
220     memset(ctx->p_prov, 0, sizeof(struct _mscrypt_prov));
221     return(0);
222 }
223 
224 static void
xmlSecMSCryptoKeyDataCtxDestroyProvider(xmlSecMSCryptoKeyDataCtxPtr ctx)225 xmlSecMSCryptoKeyDataCtxDestroyProvider(xmlSecMSCryptoKeyDataCtxPtr ctx) {
226     xmlSecAssert(ctx != NULL);
227 
228     if(ctx->p_prov != NULL) {
229         if(InterlockedDecrement(&(ctx->p_prov->refcnt)) <= 0) {
230             if((ctx->p_prov->hProv != 0) && (ctx->p_prov->fCallerFreeProv)) {
231                 CryptReleaseContext(ctx->p_prov->hProv, 0) ;
232             }
233             memset(ctx->p_prov, 0, sizeof(struct _mscrypt_prov));
234             xmlFree(ctx->p_prov) ;
235         }
236         ctx->p_prov = NULL;
237     }
238 }
239 
240 static int
xmlSecMSCryptoKeyDataCtxSetProvider(xmlSecMSCryptoKeyDataCtxPtr ctx,HCRYPTPROV hProv,BOOL fCallerFreeProv)241 xmlSecMSCryptoKeyDataCtxSetProvider(xmlSecMSCryptoKeyDataCtxPtr ctx, HCRYPTPROV hProv, BOOL fCallerFreeProv)
242 {
243     int ret;
244 
245     xmlSecAssert2(ctx != NULL, -1);
246 
247     xmlSecMSCryptoKeyDataCtxDestroyProvider(ctx);
248 
249     if((ctx->p_prov != NULL) && (ctx->p_prov->refcnt == 1)) {
250         if((ctx->p_prov->hProv != 0) && (ctx->p_prov->fCallerFreeProv)) {
251                 CryptReleaseContext(ctx->p_prov->hProv, 0) ;
252         }
253         memset(ctx->p_prov, 0, sizeof(struct _mscrypt_prov));
254     } else {
255         xmlSecMSCryptoKeyDataCtxDestroyProvider(ctx);
256         ret = xmlSecMSCryptoKeyDataCtxCreateProvider(ctx);
257         if(ret != 0) {
258             xmlSecInternalError("xmlSecMSCryptoKeyDataCtxCreateProvider", NULL);
259             return(-1);
260         }
261     }
262 
263     ctx->p_prov->hProv = hProv;
264     ctx->p_prov->fCallerFreeProv = fCallerFreeProv;
265     ctx->p_prov->refcnt = 1;
266     return(0);
267 }
268 
269 static int
xmlSecMSCryptoKeyDataCtxDuplicateProvider(xmlSecMSCryptoKeyDataCtxPtr ctxDst,xmlSecMSCryptoKeyDataCtxPtr ctxSrc)270 xmlSecMSCryptoKeyDataCtxDuplicateProvider(xmlSecMSCryptoKeyDataCtxPtr ctxDst, xmlSecMSCryptoKeyDataCtxPtr ctxSrc) {
271     xmlSecAssert2(ctxDst != NULL, -1);
272     xmlSecAssert2(ctxSrc != NULL, -1);
273 
274     xmlSecMSCryptoKeyDataCtxDestroyProvider(ctxDst);
275 
276     if (ctxSrc->p_prov != NULL) {
277         ctxDst->p_prov = ctxSrc->p_prov;
278         InterlockedIncrement(&(ctxDst->p_prov->refcnt));
279     }
280 
281     return(0);
282 }
283 
284 /********************************  Key  *****************************************/
285 #define xmlSecMSCryptoKeyDataCtxGetKey(ctx)            (((ctx)->p_key) ? ((ctx)->p_key->hKey) : 0)
286 
287 static int
xmlSecMSCryptoKeyDataCtxCreateKey(xmlSecMSCryptoKeyDataCtxPtr ctx)288 xmlSecMSCryptoKeyDataCtxCreateKey(xmlSecMSCryptoKeyDataCtxPtr ctx) {
289     xmlSecAssert2(ctx != NULL, -1);
290 
291     ctx->p_key = (struct _mscrypt_key*)xmlMalloc(sizeof(struct _mscrypt_key));
292     if(ctx->p_key == NULL ) {
293         xmlSecMallocError(sizeof(struct _mscrypt_key), NULL);
294         return(-1);
295     }
296     memset(ctx->p_key, 0, sizeof(struct _mscrypt_key));
297     return(0);
298 }
299 
300 static void
xmlSecMSCryptoKeyDataCtxDestroyKey(xmlSecMSCryptoKeyDataCtxPtr ctx)301 xmlSecMSCryptoKeyDataCtxDestroyKey(xmlSecMSCryptoKeyDataCtxPtr ctx) {
302     xmlSecAssert(ctx != NULL);
303 
304         if(ctx->p_key != NULL) {
305                 if(InterlockedDecrement(&(ctx->p_key->refcnt)) <= 0) {
306                         if(ctx->p_key->hKey != 0) {
307                                 CryptDestroyKey(ctx->p_key->hKey) ;
308                         }
309             memset(ctx->p_key, 0, sizeof(struct _mscrypt_key));
310                         xmlFree(ctx->p_key) ;
311                 }
312         ctx->p_key = NULL;
313         }
314 }
315 
316 static int
xmlSecMSCryptoKeyDataCtxSetKey(xmlSecMSCryptoKeyDataCtxPtr ctx,HCRYPTKEY hKey)317 xmlSecMSCryptoKeyDataCtxSetKey(xmlSecMSCryptoKeyDataCtxPtr ctx, HCRYPTKEY hKey) {
318     int ret;
319     xmlSecAssert2(ctx != NULL, -1);
320 
321     if((ctx->p_key != NULL) && (ctx->p_key->refcnt == 1)) {
322         if(ctx->p_key->hKey != 0) {
323             CryptDestroyKey(ctx->p_key->hKey) ;
324         }
325         memset(ctx->p_key, 0, sizeof(struct _mscrypt_key));
326     } else {
327         xmlSecMSCryptoKeyDataCtxDestroyKey(ctx);
328         ret = xmlSecMSCryptoKeyDataCtxCreateKey(ctx);
329         if(ret != 0) {
330             xmlSecInternalError("xmlSecMSCryptoKeyDataCtxCreateKey", NULL);
331             return(-1);
332         }
333     }
334     ctx->p_key->hKey = hKey;
335     ctx->p_key->refcnt = 1;
336     return(0);
337 }
338 
339 static int
xmlSecMSCryptoKeyDataCtxDuplicateKey(xmlSecMSCryptoKeyDataCtxPtr ctxDst,xmlSecMSCryptoKeyDataCtxPtr ctxSrc)340 xmlSecMSCryptoKeyDataCtxDuplicateKey(xmlSecMSCryptoKeyDataCtxPtr ctxDst, xmlSecMSCryptoKeyDataCtxPtr ctxSrc) {
341     xmlSecAssert2(ctxDst != NULL, -1);
342     xmlSecAssert2(ctxSrc != NULL, -1);
343 
344     xmlSecMSCryptoKeyDataCtxDestroyKey(ctxDst);
345     if (ctxSrc->p_key != NULL) {
346         ctxDst->p_key = ctxSrc->p_key;
347         InterlockedIncrement(&(ctxDst->p_key->refcnt));
348     }
349 
350     return(0);
351 }
352 
353 #endif /* XMLSEC_MSCRYPTO_NT4 */
354 
355 /******************************** Cert *****************************************/
356 #define xmlSecMSCryptoKeyDataCtxGetCert(ctx)            ((ctx)->pCert)
357 
358 static void
xmlSecMSCryptoKeyDataCtxCreateCert(xmlSecMSCryptoKeyDataCtxPtr ctx)359 xmlSecMSCryptoKeyDataCtxCreateCert(xmlSecMSCryptoKeyDataCtxPtr ctx) {
360     xmlSecAssert(ctx != NULL);
361 
362     ctx->pCert = NULL;
363 }
364 
365 static void
xmlSecMSCryptoKeyDataCtxDestroyCert(xmlSecMSCryptoKeyDataCtxPtr ctx)366 xmlSecMSCryptoKeyDataCtxDestroyCert(xmlSecMSCryptoKeyDataCtxPtr ctx) {
367     xmlSecAssert(ctx != NULL);
368 
369     if(ctx->pCert != NULL) {
370             CertFreeCertificateContext(ctx->pCert);
371     }
372     ctx->pCert = NULL;
373 }
374 
375 static int
xmlSecMSCryptoKeyDataCtxSetCert(xmlSecMSCryptoKeyDataCtxPtr ctx,PCCERT_CONTEXT pCert)376 xmlSecMSCryptoKeyDataCtxSetCert(xmlSecMSCryptoKeyDataCtxPtr ctx, PCCERT_CONTEXT pCert) {
377     xmlSecAssert2(ctx != NULL, -1);
378 
379     xmlSecMSCryptoKeyDataCtxDestroyCert(ctx);
380     ctx->pCert = pCert;
381     return(0);
382 }
383 
384 static int
xmlSecMSCryptoKeyDataCtxDuplicateCert(xmlSecMSCryptoKeyDataCtxPtr ctxDst,xmlSecMSCryptoKeyDataCtxPtr ctxSrc)385 xmlSecMSCryptoKeyDataCtxDuplicateCert(xmlSecMSCryptoKeyDataCtxPtr ctxDst, xmlSecMSCryptoKeyDataCtxPtr ctxSrc) {
386     xmlSecAssert2(ctxDst != NULL, -1);
387     xmlSecAssert2(ctxSrc != NULL, -1);
388 
389     xmlSecMSCryptoKeyDataCtxDestroyCert(ctxDst);
390     if(ctxSrc->pCert != NULL) {
391             ctxDst->pCert = xmlSecMSCryptoCertDup(ctxSrc->pCert);
392             if(ctxDst->pCert == NULL) {
393                 xmlSecInternalError("xmlSecMSCryptoPCCDup", NULL);
394                 return(-1);
395             }
396     }
397     return(0);
398 }
399 
400 /******************************************************************************
401  *
402  * xmlSecMSCryptoKeyDataCtx is located after xmlSecTransform
403  *
404  *****************************************************************************/
405 #define xmlSecMSCryptoKeyDataSize       \
406     (sizeof(xmlSecKeyData) + sizeof(xmlSecMSCryptoKeyDataCtx))
407 #define xmlSecMSCryptoKeyDataGetCtx(data) \
408     ((xmlSecMSCryptoKeyDataCtxPtr)(((xmlSecByte*)(data)) + sizeof(xmlSecKeyData)))
409 
410 static int      xmlSecMSCryptoKeyDataDuplicate  (xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src);
411 static void             xmlSecMSCryptoKeyDataFinalize   (xmlSecKeyDataPtr data);
412 static int              xmlSecMSCryptoKeyDataGetSize    (xmlSecKeyDataPtr data);
413 
414 /**
415  * xmlSecMSCryptoKeyDataAdoptCert:
416  * @data:               the pointer to MSCrypto pccert data.
417  * @pCert:              the pointer to PCCERT key.
418  *
419  * Sets the value of key data.
420  *
421  * Returns: 0 on success or a negative value otherwise.
422  */
423 static int
xmlSecMSCryptoKeyDataAdoptCert(xmlSecKeyDataPtr data,PCCERT_CONTEXT pCert,xmlSecKeyDataType type)424 xmlSecMSCryptoKeyDataAdoptCert(xmlSecKeyDataPtr data, PCCERT_CONTEXT pCert, xmlSecKeyDataType type) {
425     xmlSecMSCryptoKeyDataCtxPtr ctx;
426     HCRYPTKEY hKey = 0;
427     int ret;
428 
429     xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
430     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), -1);
431     xmlSecAssert2(pCert != NULL, -1);
432     xmlSecAssert2(pCert->pCertInfo != NULL, -1);
433     xmlSecAssert2((type & (xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate)) != 0, -1);
434 
435     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
436     xmlSecAssert2(ctx != NULL, -1);
437 
438     xmlSecMSCryptoKeyDataCtxDestroyProvider(ctx);
439     xmlSecMSCryptoKeyDataCtxDestroyKey(ctx);
440     xmlSecMSCryptoKeyDataCtxDestroyCert(ctx);
441 
442     ctx->type = type;
443 
444     /* Now we acquire a context for this key(pair). The context is needed
445      * for the real crypto stuff in MS Crypto.
446      */
447     if((type & xmlSecKeyDataTypePrivate) != 0){
448         HCRYPTPROV hProv = 0;
449         BOOL fCallerFreeProv = FALSE;
450 
451         if (!CryptAcquireCertificatePrivateKey(pCert,
452                     CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
453                     NULL,
454                     &hProv,
455                     &(ctx->dwKeySpec),
456                     &fCallerFreeProv)) {
457                 xmlSecMSCryptoError("CryptAcquireCertificatePrivateKey", NULL);
458                 return(-1);
459         }
460         ret = xmlSecMSCryptoKeyDataCtxSetProvider(ctx, hProv, fCallerFreeProv);
461         if(ret != 0) {
462             xmlSecInternalError("xmlSecMSCryptoKeyDataCtxSetProvider", NULL);
463             return(-1);
464         }
465     } else if((type & xmlSecKeyDataTypePublic) != 0){
466         HCRYPTPROV hProv;
467 
468         hProv = xmlSecMSCryptoFindProvider(ctx->providers, NULL, CRYPT_VERIFYCONTEXT, FALSE);
469         if (hProv == 0) {
470             xmlSecInternalError("xmlSecMSCryptoFindProvider", NULL);
471             return(-1);
472         }
473         ret = xmlSecMSCryptoKeyDataCtxSetProvider(ctx, hProv, TRUE);
474         if(ret != 0) {
475             xmlSecInternalError("xmlSecMSCryptoKeyDataCtxSetProvider", NULL);
476             return(-1);
477         }
478         ctx->dwKeySpec = 0;
479     } else {
480         xmlSecInvalidIntegerTypeError("keytype", type, "supported keytype", NULL);
481         return(-1);
482     }
483 
484     /* CryptImportPublicKeyInfo is only needed when a real key handle
485      * is needed. The key handle is needed for de/encrypting and for
486      * verifying of a signature, *not* for signing. We could call
487      * CryptImportPublicKeyInfo in xmlSecMSCryptoKeyDataGetKey instead
488      * so no unnecessary calls to CryptImportPublicKeyInfo are being
489      * made. WK
490      */
491     if(!CryptImportPublicKeyInfo(xmlSecMSCryptoKeyDataCtxGetProvider(ctx),
492                 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
493                 &(pCert->pCertInfo->SubjectPublicKeyInfo),
494                 &hKey)) {
495             xmlSecMSCryptoError("CryptImportPublicKeyInfo", NULL);
496             return(-1);
497     }
498 
499     ret = xmlSecMSCryptoKeyDataCtxSetKey(ctx, hKey);
500     if(ret != 0) {
501         xmlSecInternalError("xmlSecMSCryptoKeyDataCtxSetKey", NULL);
502         return(-1);
503     }
504     ret = xmlSecMSCryptoKeyDataCtxSetCert(ctx, pCert);
505     if(ret != 0) {
506         xmlSecInternalError("xmlSecMSCryptoKeyDataCtxSetCert", NULL);
507         return(-1);
508     }
509     return(0);
510 }
511 
512 static int
xmlSecMSCryptoKeyDataAdoptKey(xmlSecKeyDataPtr data,HCRYPTPROV hProv,BOOL fCallerFreeProv,HCRYPTKEY hKey,DWORD dwKeySpec,xmlSecKeyDataType type)513 xmlSecMSCryptoKeyDataAdoptKey(xmlSecKeyDataPtr data,
514                               HCRYPTPROV hProv,
515                               BOOL fCallerFreeProv,
516                               HCRYPTKEY hKey,
517                               DWORD dwKeySpec,
518                               xmlSecKeyDataType type) {
519     xmlSecMSCryptoKeyDataCtxPtr ctx;
520     int ret;
521 
522     xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
523     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), -1);
524     xmlSecAssert2(hKey != 0, -1);
525     xmlSecAssert2(type & (xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate), -1);
526 
527     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
528     xmlSecAssert2(ctx != NULL, -1);
529 
530     ret = xmlSecMSCryptoKeyDataCtxSetProvider(ctx, hProv, fCallerFreeProv);
531     if(ret != 0) {
532         xmlSecInternalError("xmlSecMSCryptoKeyDataCtxSetProvider", NULL);
533         return(-1);
534     }
535     ret = xmlSecMSCryptoKeyDataCtxSetKey(ctx, hKey);
536     if(ret != 0) {
537         xmlSecInternalError("xmlSecMSCryptoKeyDataCtxSetKey", NULL);
538         return(-1);
539     }
540     ret = xmlSecMSCryptoKeyDataCtxSetCert(ctx, NULL);
541     if(ret != 0) {
542         xmlSecInternalError("xmlSecMSCryptoKeyDataCtxSetCert", NULL);
543         return(-1);
544     }
545 
546     ctx->dwKeySpec       = dwKeySpec;
547     ctx->type            = type;
548 
549     return(0);
550 }
551 
552 /**
553  * xmlSecMSCryptoKeyDataGetKey:
554  * @data:               the key data to retrieve certificate from.
555  * @type:              type of key requested (public/private)
556  *
557  * Native MSCrypto key retrieval from xmlsec keydata. The
558  * returned HKEY must not be destroyed by the caller.
559  *
560  * Returns: HKEY on success or NULL otherwise.
561  */
562 HCRYPTKEY
xmlSecMSCryptoKeyDataGetKey(xmlSecKeyDataPtr data,xmlSecKeyDataType type)563 xmlSecMSCryptoKeyDataGetKey(xmlSecKeyDataPtr data, xmlSecKeyDataType type) {
564     xmlSecMSCryptoKeyDataCtxPtr ctx;
565 
566     xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
567     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), 0);
568 
569     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
570     xmlSecAssert2(ctx != NULL, 0);
571     UNREFERENCED_PARAMETER(type);
572 
573     return(xmlSecMSCryptoKeyDataCtxGetKey(ctx));
574 }
575 
576 /**
577  * xmlSecMSCryptoKeyDataGetDecryptKey:
578  * @data:       the key data pointer
579  *
580  * Native MSCrypto decrypt key retrieval from xmlsec keydata. The
581  * returned HKEY must not be destroyed by the caller.
582  *
583  * Returns: HKEY on success or NULL otherwise.
584  */
585 HCRYPTKEY
xmlSecMSCryptoKeyDataGetDecryptKey(xmlSecKeyDataPtr data)586 xmlSecMSCryptoKeyDataGetDecryptKey(xmlSecKeyDataPtr data) {
587         xmlSecMSCryptoKeyDataCtxPtr ctx;
588         HCRYPTKEY hKey;
589 
590         xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
591         xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), 0);
592 
593         ctx = xmlSecMSCryptoKeyDataGetCtx(data);
594         xmlSecAssert2(ctx != NULL, 0);
595 
596         if( !CryptGetUserKey(xmlSecMSCryptoKeyDataCtxGetProvider(ctx), AT_KEYEXCHANGE, &(hKey))) {
597                 xmlSecMSCryptoError("CryptGetUserKey", NULL);
598                 return(0);
599         }
600         return (hKey);
601 }
602 
603 /**
604  * xmlSecMSCryptoKeyDataGetCert:
605  * @data:               the key data to retrieve certificate from.
606  *
607  * Native MSCrypto certificate retrieval from xmlsec keydata. The
608  * returned PCCERT_CONTEXT must not be released by the caller.
609  *
610  * Returns: PCCERT_CONTEXT on success or NULL otherwise.
611  */
612 PCCERT_CONTEXT
xmlSecMSCryptoKeyDataGetCert(xmlSecKeyDataPtr data)613 xmlSecMSCryptoKeyDataGetCert(xmlSecKeyDataPtr data) {
614     xmlSecMSCryptoKeyDataCtxPtr ctx;
615 
616     xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
617     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), 0);
618 
619     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
620     xmlSecAssert2(ctx != NULL, 0);
621 
622     return(xmlSecMSCryptoKeyDataCtxGetCert(ctx));
623 }
624 
625 /**
626  * xmlSecMSCryptoKeyDataGetMSCryptoProvider:
627  * @data:              the key data
628  *
629  * Gets crypto provider handle
630  *
631  * Returns: the crypto provider handler or 0 if there is an error.
632  */
633 HCRYPTPROV
xmlSecMSCryptoKeyDataGetMSCryptoProvider(xmlSecKeyDataPtr data)634 xmlSecMSCryptoKeyDataGetMSCryptoProvider(xmlSecKeyDataPtr data) {
635     xmlSecMSCryptoKeyDataCtxPtr ctx;
636 
637     xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
638     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), 0);
639 
640     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
641     xmlSecAssert2(ctx != NULL, 0);
642 
643     return(xmlSecMSCryptoKeyDataCtxGetProvider(ctx));
644 }
645 
646 /**
647  * xmlSecMSCryptoKeyDataGetMSCryptoKeySpec:
648  * @data:              the key data
649  *
650  * Gets key spec info.
651  *
652  * Returns: the key spec info from key data
653  */
654 DWORD
xmlSecMSCryptoKeyDataGetMSCryptoKeySpec(xmlSecKeyDataPtr data)655 xmlSecMSCryptoKeyDataGetMSCryptoKeySpec(xmlSecKeyDataPtr data) {
656     xmlSecMSCryptoKeyDataCtxPtr ctx;
657 
658     xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
659     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), 0);
660 
661     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
662     xmlSecAssert2(ctx != NULL, 0);
663 
664     return(ctx->dwKeySpec);
665 }
666 
667 /**
668  * xmlSecMSCryptoKeyDataGetMSCryptoProviderInfo:
669  * @data:              the key data
670  *
671  * Gets key provider info.
672  *
673  * Returns: the key provider info.
674  */
675 PCRYPT_KEY_PROV_INFO
xmlSecMSCryptoKeyDataGetMSCryptoProviderInfo(xmlSecKeyDataPtr data)676 xmlSecMSCryptoKeyDataGetMSCryptoProviderInfo(xmlSecKeyDataPtr data) {
677     xmlSecMSCryptoKeyDataCtxPtr ctx;
678     LPBYTE pInfoData = NULL;
679     DWORD dwInfoDataLength = 0;
680 
681     xmlSecAssert2(data != NULL, NULL);
682 
683     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
684     xmlSecAssert2(ctx != NULL, NULL);
685     xmlSecAssert2(ctx->pCert != NULL, NULL);
686 
687     if(!CertGetCertificateContextProperty(ctx->pCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwInfoDataLength)) {
688         xmlSecMSCryptoError("CertGetCertificateContextProperty", NULL);
689         return NULL;
690     }
691 
692     if(dwInfoDataLength > 0) {
693         pInfoData = malloc(dwInfoDataLength * sizeof(BYTE));
694 
695         if(!CertGetCertificateContextProperty(ctx->pCert, CERT_KEY_PROV_INFO_PROP_ID, pInfoData, &dwInfoDataLength)) {
696             xmlSecMSCryptoError("CertGetCertificateContextProperty", NULL);
697             free(pInfoData);
698             return NULL;
699         }
700     }
701 
702     return (PCRYPT_KEY_PROV_INFO)pInfoData;
703 }
704 
705 static int
xmlSecMSCryptoKeyDataDuplicate(xmlSecKeyDataPtr dst,xmlSecKeyDataPtr src)706 xmlSecMSCryptoKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
707     xmlSecMSCryptoKeyDataCtxPtr ctxDst;
708     xmlSecMSCryptoKeyDataCtxPtr ctxSrc;
709 
710     xmlSecAssert2(xmlSecKeyDataIsValid(dst), -1);
711     xmlSecAssert2(xmlSecKeyDataCheckSize(dst, xmlSecMSCryptoKeyDataSize), -1);
712     xmlSecAssert2(xmlSecKeyDataIsValid(src), -1);
713     xmlSecAssert2(xmlSecKeyDataCheckSize(src, xmlSecMSCryptoKeyDataSize), -1);
714 
715     ctxDst = xmlSecMSCryptoKeyDataGetCtx(dst);
716     xmlSecAssert2(ctxDst != NULL, -1);
717 
718     ctxSrc = xmlSecMSCryptoKeyDataGetCtx(src);
719     xmlSecAssert2(ctxSrc != NULL, -1);
720 
721     if(xmlSecMSCryptoKeyDataCtxDuplicateProvider(ctxDst, ctxSrc) < 0) {
722             xmlSecInternalError("xmlSecMSCryptoKeyDataCtxDuplicateProvider",
723                                 xmlSecKeyDataGetName(dst));
724             return(-1);
725     }
726 
727     if(xmlSecMSCryptoKeyDataCtxDuplicateKey(ctxDst, ctxSrc) < 0) {
728             xmlSecInternalError("xmlSecMSCryptoKeyDataCtxDuplicateKey",
729                                 xmlSecKeyDataGetName(dst));
730             return(-1);
731     }
732 
733     if(xmlSecMSCryptoKeyDataCtxDuplicateCert(ctxDst, ctxSrc) < 0) {
734             xmlSecInternalError("xmlSecMSCryptoKeyDataCtxDuplicateCert",
735                                 xmlSecKeyDataGetName(dst));
736             return(-1);
737     }
738 
739     ctxDst->dwKeySpec       = ctxSrc->dwKeySpec;
740     ctxDst->providers       = ctxSrc->providers;
741     ctxDst->type            = ctxSrc->type;
742 
743     return(0);
744 }
745 
746 static int
xmlSecMSCryptoKeyDataInitialize(xmlSecKeyDataPtr data)747 xmlSecMSCryptoKeyDataInitialize(xmlSecKeyDataPtr data) {
748     xmlSecMSCryptoKeyDataCtxPtr ctx;
749     int ret;
750 
751     xmlSecAssert2(xmlSecKeyDataIsValid(data), -1);
752     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), -1);
753 
754     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
755     xmlSecAssert2(ctx != NULL, -1);
756 
757     memset(ctx, 0, sizeof(xmlSecMSCryptoKeyDataCtx));
758 
759     ret = xmlSecMSCryptoKeyDataCtxCreateProvider(ctx);
760     if(ret != 0) {
761         xmlSecInternalError("xmlSecMSCryptoKeyDataCtxCreateProvider", NULL);
762         return(-1);
763     }
764     ret = xmlSecMSCryptoKeyDataCtxCreateKey(ctx);
765     if(ret != 0) {
766         xmlSecInternalError("xmlSecMSCryptoKeyDataCtxCreateKey", NULL);
767         return(-1);
768     }
769     xmlSecMSCryptoKeyDataCtxCreateCert(ctx);
770     return(0);
771 }
772 
773 static void
xmlSecMSCryptoKeyDataFinalize(xmlSecKeyDataPtr data)774 xmlSecMSCryptoKeyDataFinalize(xmlSecKeyDataPtr data) {
775     xmlSecMSCryptoKeyDataCtxPtr ctx;
776 
777     xmlSecAssert(xmlSecKeyDataIsValid(data));
778     xmlSecAssert(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize));
779 
780     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
781     xmlSecAssert(ctx != NULL);
782 
783     xmlSecMSCryptoKeyDataCtxDestroyKey(ctx);
784     xmlSecMSCryptoKeyDataCtxDestroyCert(ctx);
785     xmlSecMSCryptoKeyDataCtxDestroyProvider(ctx);
786 
787     memset(ctx, 0, sizeof(xmlSecMSCryptoKeyDataCtx));
788 }
789 
790 static int
xmlSecMSCryptoKeyDataGetSize(xmlSecKeyDataPtr data)791 xmlSecMSCryptoKeyDataGetSize(xmlSecKeyDataPtr data) {
792     xmlSecMSCryptoKeyDataCtxPtr ctx;
793 
794     xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
795     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), 0);
796 
797     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
798     xmlSecAssert2(ctx != NULL, 0);
799 
800     if(xmlSecMSCryptoKeyDataCtxGetCert(ctx) != NULL) {
801         xmlSecAssert2(xmlSecMSCryptoKeyDataCtxGetCert(ctx)->pCertInfo != NULL, 0);
802         return (CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
803                     &(xmlSecMSCryptoKeyDataCtxGetCert(ctx)->pCertInfo->SubjectPublicKeyInfo)));
804     } else if (xmlSecMSCryptoKeyDataCtxGetKey(ctx) != 0) {
805         DWORD length = 0;
806             DWORD lenlen = sizeof(DWORD);
807 
808         if (!CryptGetKeyParam(xmlSecMSCryptoKeyDataCtxGetKey(ctx), KP_KEYLEN, (BYTE *)&length, &lenlen, 0)) {
809             xmlSecMSCryptoError("CertDuplicateCertificateContext", NULL);
810             return(0);
811         }
812         return(length);
813     }
814 
815     return (0);
816 }
817 
818 static xmlSecKeyDataType
xmlSecMSCryptoKeyDataGetType(xmlSecKeyDataPtr data)819 xmlSecMSCryptoKeyDataGetType(xmlSecKeyDataPtr data) {
820     xmlSecMSCryptoKeyDataCtxPtr ctx;
821 
822     xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
823     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), xmlSecKeyDataTypeUnknown);
824 
825     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
826     xmlSecAssert2(ctx != NULL, xmlSecKeyDataTypeUnknown);
827 
828     /* We could make a call to CryptFindCertificateKeyProvInfo here, to find out if
829      * we *really* have a private key or not. However if the certificate is not
830      * linked to a private key, the call takes an ridiculous amount of time.
831      * the way it is now is better I think. WK.
832      */
833     return(ctx->type);
834 }
835 
836 /**
837  * xmlSecMSCryptoCertDup:
838  * @pCert:              the pointer to cert.
839  *
840  * Duplicates the @pCert.
841  *
842  * Returns: pointer to newly created PCCERT_CONTEXT object or
843  * NULL if an error occurs.
844  */
xmlSecMSCryptoCertDup(PCCERT_CONTEXT pCert)845 PCCERT_CONTEXT xmlSecMSCryptoCertDup(PCCERT_CONTEXT pCert) {
846     PCCERT_CONTEXT ret;
847 
848     xmlSecAssert2(pCert != NULL, NULL);
849 
850     ret = CertDuplicateCertificateContext(pCert);
851     if(ret == NULL) {
852         xmlSecMSCryptoError("CertDuplicateCertificateContext", NULL);
853         return(NULL);
854     }
855 
856     return(ret);
857 }
858 
859 
860 /**
861  * xmlSecMSCryptoCertAdopt:
862  * @pCert:              the pointer to cert.
863  * @type:               the expected key type.
864  *
865  * Creates key data value from the cert.
866  *
867  * Returns: pointer to newly created xmlsec key or NULL if an error occurs.
868  */
869 xmlSecKeyDataPtr
xmlSecMSCryptoCertAdopt(PCCERT_CONTEXT pCert,xmlSecKeyDataType type)870 xmlSecMSCryptoCertAdopt(PCCERT_CONTEXT pCert, xmlSecKeyDataType type) {
871     xmlSecKeyDataPtr data = NULL;
872     int ret;
873 
874     xmlSecAssert2(pCert != NULL, NULL);
875     xmlSecAssert2(pCert->pCertInfo != NULL, NULL);
876     xmlSecAssert2(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId != NULL, NULL);
877 
878 #ifndef XMLSEC_NO_RSA
879     if (!strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId, szOID_RSA_RSA)) {
880         data = xmlSecKeyDataCreate(xmlSecMSCryptoKeyDataRsaId);
881         if(data == NULL) {
882             xmlSecInternalError("xmlSecKeyDataCreate(KeyDataRsaId)", NULL);
883             return(NULL);
884         }
885     }
886 #endif /* XMLSEC_NO_RSA */
887 
888 #ifndef XMLSEC_NO_DSA
889     if (!strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId, szOID_X957_DSA /*szOID_DSALG_SIGN*/)) {
890         data = xmlSecKeyDataCreate(xmlSecMSCryptoKeyDataDsaId);
891         if(data == NULL) {
892                 xmlSecInternalError("xmlSecKeyDataCreate(KeyDataDsaId)", NULL);
893                 return(NULL);
894         }
895     }
896 #endif /* XMLSEC_NO_DSA */
897 
898 #ifndef XMLSEC_NO_GOST
899     if (!strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,  szOID_MAGPRO_PUBKEY_SIGN_R3410_2001_CP) ||
900         !strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,  szOID_MAGPRO_PUBKEY_SIGN_R3410_2001) ||
901           !strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,  szOID_MAGPRO_PUBKEY_SIGN_R3410_94_CP)) {
902         data = xmlSecKeyDataCreate(xmlSecMSCryptoKeyDataGost2001Id);
903         if(data == NULL) {
904                 xmlSecInternalError("xmlSecKeyDataCreate(KeyDataGost2001Id)", NULL);
905                 return(NULL);
906         }
907     }
908 #endif /* XMLSEC_NO_GOST*/
909 #ifndef XMLSEC_NO_GOST2012
910     if (!strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,  szOID_CP_GOST_R3410_12_256) ||
911         !strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,  szOID_CP_GOST_R3411_12_256_R3410)) {
912         data = xmlSecKeyDataCreate(xmlSecMSCryptoKeyDataGost2012_256Id);
913         if(data == NULL) {
914                 xmlSecInternalError("xmlSecKeyDataCreate(KeyDataGost2012_256Id)", NULL);
915                 return(NULL);
916         }
917     }
918     if (!strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,  szOID_CP_GOST_R3410_12_512) ||
919         !strcmp(pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,  szOID_CP_GOST_R3411_12_512_R3410)) {
920         data = xmlSecKeyDataCreate(xmlSecMSCryptoKeyDataGost2012_512Id);
921         if(data == NULL) {
922                 xmlSecInternalError("xmlSecKeyDataCreate(KeyDataGost2012_512Id)", NULL);
923                 return(NULL);
924         }
925     }
926 #endif /* XMLSEC_NO_GOST2012 */
927 
928     if (NULL == data) {
929         xmlSecInvalidStringTypeError("PCCERT_CONTEXT key type",
930                 pCert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,
931                 "unsupported keytype", NULL);
932         return(NULL);
933     }
934 
935     xmlSecAssert2(data != NULL, NULL);
936 
937     ret = xmlSecMSCryptoKeyDataAdoptCert(data, pCert, type);
938     if(ret < 0) {
939         xmlSecInternalError("xmlSecMSCryptoPCCDataAdoptPCC", NULL);
940         xmlSecKeyDataDestroy(data);
941         return(NULL);
942     }
943     return(data);
944 }
945 
946 
947 #ifndef XMLSEC_NO_RSA
948 /**************************************************************************
949  *
950  * <dsig:RSAKeyValue> processing
951  *
952  * http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
953  * The RSAKeyValue Element
954  *
955  * RSA key values have two fields: Modulus and Exponent.
956  *
957  * <RSAKeyValue>
958  *   <Modulus>xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6W
959  *     jubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV
960  *        5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U=
961  *   </Modulus>
962  *   <Exponent>AQAB</Exponent>
963  * </RSAKeyValue>
964  *
965  * Arbitrary-length integers (e.g. "bignums" such as RSA moduli) are
966  * represented in XML as octet strings as defined by the ds:CryptoBinary type.
967  *
968  * Schema Definition:
969  *
970  * <element name="RSAKeyValue" type="ds:RSAKeyValueType"/>
971  * <complexType name="RSAKeyValueType">
972  *   <sequence>
973  *     <element name="Modulus" type="ds:CryptoBinary"/>
974  *     <element name="Exponent" type="ds:CryptoBinary"/>
975  *   </sequence>
976  * </complexType>
977  *
978  * DTD Definition:
979  *
980  * <!ELEMENT RSAKeyValue (Modulus, Exponent) >
981  * <!ELEMENT Modulus (#PCDATA) >
982  * <!ELEMENT Exponent (#PCDATA) >
983  *
984  * ============================================================================
985  *
986  *
987  *************************************************************************/
988 
989 static int      xmlSecMSCryptoKeyDataRsaInitialize(xmlSecKeyDataPtr data);
990 static int      xmlSecMSCryptoKeyDataRsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src);
991 static void     xmlSecMSCryptoKeyDataRsaFinalize(xmlSecKeyDataPtr data);
992 static int      xmlSecMSCryptoKeyDataRsaXmlRead(xmlSecKeyDataId id,
993                                                 xmlSecKeyPtr key,
994                                                 xmlNodePtr node,
995                                                 xmlSecKeyInfoCtxPtr keyInfoCtx);
996 static int      xmlSecMSCryptoKeyDataRsaXmlWrite(xmlSecKeyDataId id,
997                                                  xmlSecKeyPtr key,
998                                                  xmlNodePtr node,
999                                                  xmlSecKeyInfoCtxPtr keyInfoCtx);
1000 static int      xmlSecMSCryptoKeyDataRsaGenerate(xmlSecKeyDataPtr data,
1001                                                  xmlSecSize sizeBits,
1002                                                  xmlSecKeyDataType type);
1003 
1004 static xmlSecKeyDataType    xmlSecMSCryptoKeyDataRsaGetType(xmlSecKeyDataPtr data);
1005 static xmlSecSize           xmlSecMSCryptoKeyDataRsaGetSize(xmlSecKeyDataPtr data);
1006 static void                 xmlSecMSCryptoKeyDataRsaDebugDump(xmlSecKeyDataPtr data, FILE* output);
1007 static void                 xmlSecMSCryptoKeyDataRsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output);
1008 
1009 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataRsaKlass = {
1010     sizeof(xmlSecKeyDataKlass),
1011     xmlSecMSCryptoKeyDataSize,
1012 
1013     /* data */
1014     xmlSecNameRSAKeyValue,
1015     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
1016                                                 /* xmlSecKeyDataUsage usage; */
1017     xmlSecHrefRSAKeyValue,                      /* const xmlChar* href; */
1018     xmlSecNodeRSAKeyValue,                      /* const xmlChar* dataNodeName; */
1019     xmlSecDSigNs,                               /* const xmlChar* dataNodeNs; */
1020 
1021     /* constructors/destructor */
1022     xmlSecMSCryptoKeyDataRsaInitialize,         /* xmlSecKeyDataInitializeMethod initialize; */
1023     xmlSecMSCryptoKeyDataRsaDuplicate,          /* xmlSecKeyDataDuplicateMethod duplicate; */
1024     xmlSecMSCryptoKeyDataRsaFinalize,           /* xmlSecKeyDataFinalizeMethod finalize; */
1025     xmlSecMSCryptoKeyDataRsaGenerate,           /* xmlSecKeyDataGenerateMethod generate; */
1026 
1027     /* get info */
1028     xmlSecMSCryptoKeyDataRsaGetType,            /* xmlSecKeyDataGetTypeMethod getType; */
1029     xmlSecMSCryptoKeyDataRsaGetSize,            /* xmlSecKeyDataGetSizeMethod getSize; */
1030     NULL,                                       /* xmlSecKeyDataGetIdentifier getIdentifier; */
1031 
1032     /* read/write */
1033     xmlSecMSCryptoKeyDataRsaXmlRead,            /* xmlSecKeyDataXmlReadMethod xmlRead; */
1034     xmlSecMSCryptoKeyDataRsaXmlWrite,           /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
1035     NULL,                                       /* xmlSecKeyDataBinReadMethod binRead; */
1036     NULL,                                       /* xmlSecKeyDataBinWriteMethod binWrite; */
1037 
1038     /* debug */
1039     xmlSecMSCryptoKeyDataRsaDebugDump,          /* xmlSecKeyDataDebugDumpMethod debugDump; */
1040     xmlSecMSCryptoKeyDataRsaDebugXmlDump,       /* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
1041 
1042     /* reserved for the future */
1043     NULL,                                       /* void* reserved0; */
1044     NULL,                                       /* void* reserved1; */
1045 };
1046 
1047 /* Ordered list of providers to search for algorithm implementation using
1048  * xmlSecMSCryptoFindProvider() function
1049  *
1050  * MUST END with { NULL, 0 } !!!
1051  */
1052 static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Rsa[] = {
1053     { XMLSEC_CRYPTO_MS_ENH_RSA_AES_PROV,                PROV_RSA_AES},
1054     { XMLSEC_CRYPTO_MS_ENH_RSA_AES_PROV_PROTOTYPE,      PROV_RSA_AES },
1055     { MS_STRONG_PROV,                                   PROV_RSA_FULL },
1056     { MS_ENHANCED_PROV,                                 PROV_RSA_FULL },
1057     { MS_DEF_PROV,                                      PROV_RSA_FULL },
1058     { NULL, 0 }
1059 };
1060 
1061 /**
1062  * xmlSecMSCryptoKeyDataRsaGetKlass:
1063  *
1064  * The MSCrypto RSA CertKey data klass.
1065  *
1066  * Returns: pointer to MSCrypto RSA key data klass.
1067  */
1068 xmlSecKeyDataId
xmlSecMSCryptoKeyDataRsaGetKlass(void)1069 xmlSecMSCryptoKeyDataRsaGetKlass(void) {
1070     return(&xmlSecMSCryptoKeyDataRsaKlass);
1071 }
1072 
1073 static int
xmlSecMSCryptoKeyDataRsaInitialize(xmlSecKeyDataPtr data)1074 xmlSecMSCryptoKeyDataRsaInitialize(xmlSecKeyDataPtr data) {
1075     xmlSecMSCryptoKeyDataCtxPtr ctx;
1076     int ret;
1077 
1078     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataRsaId), xmlSecKeyDataTypeUnknown);
1079 
1080     ret = xmlSecMSCryptoKeyDataInitialize(data);
1081     if(ret != 0) {
1082         xmlSecInternalError("xmlSecMSCryptoKeyDataInitialize", NULL);
1083         return(-1);
1084     }
1085 
1086     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
1087     xmlSecAssert2(ctx != NULL, -1);
1088 
1089     ctx->providers = xmlSecMSCryptoProviderInfo_Rsa;
1090     return(0);
1091 }
1092 
1093 static int
xmlSecMSCryptoKeyDataRsaDuplicate(xmlSecKeyDataPtr dst,xmlSecKeyDataPtr src)1094 xmlSecMSCryptoKeyDataRsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
1095     xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecMSCryptoKeyDataRsaId), -1);
1096     xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecMSCryptoKeyDataRsaId), -1);
1097 
1098     return(xmlSecMSCryptoKeyDataDuplicate(dst, src));
1099 }
1100 
1101 static void
xmlSecMSCryptoKeyDataRsaFinalize(xmlSecKeyDataPtr data)1102 xmlSecMSCryptoKeyDataRsaFinalize(xmlSecKeyDataPtr data) {
1103     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataRsaId));
1104 
1105     xmlSecMSCryptoKeyDataFinalize(data);
1106 }
1107 
1108 static int
xmlSecMSCryptoKeyDataRsaXmlRead(xmlSecKeyDataId id,xmlSecKeyPtr key,xmlNodePtr node,xmlSecKeyInfoCtxPtr keyInfoCtx)1109 xmlSecMSCryptoKeyDataRsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
1110                                 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1111     xmlSecBn modulus, exponent;
1112     xmlSecBuffer blob;
1113     unsigned int blobBufferLen;
1114     PUBLICKEYSTRUC* pubKeyStruc = NULL;
1115     RSAPUBKEY* pubKey = NULL;
1116     xmlSecByte* modulusBlob = NULL;
1117     xmlSecKeyDataPtr data = NULL;
1118     HCRYPTPROV hProv = 0;
1119     HCRYPTKEY hKey = 0;
1120     xmlNodePtr cur;
1121     int res = -1;
1122     int ret;
1123 
1124     xmlSecAssert2(id == xmlSecMSCryptoKeyDataRsaId, -1);
1125     xmlSecAssert2(key != NULL, -1);
1126     xmlSecAssert2(node != NULL, -1);
1127     xmlSecAssert2(keyInfoCtx != NULL, -1);
1128 
1129     if(xmlSecKeyGetValue(key) != NULL) {
1130         xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
1131                          xmlSecKeyDataKlassGetName(id),
1132                          "key already has a value");
1133         return(-1);
1134     }
1135 
1136     /* initialize buffers */
1137     ret = xmlSecBnInitialize(&modulus, 0);
1138     if(ret < 0) {
1139         xmlSecInternalError("xmlSecBnInitialize(modulus)",
1140                             xmlSecKeyDataKlassGetName(id));;
1141         return(-1);
1142     }
1143 
1144     ret = xmlSecBnInitialize(&exponent, 0);
1145     if(ret < 0) {
1146         xmlSecInternalError("xmlSecBnInitialize(exponent)",
1147                             xmlSecKeyDataKlassGetName(id));
1148         xmlSecBnFinalize(&modulus);
1149         return(-1);
1150     }
1151 
1152     ret = xmlSecBufferInitialize(&blob, 0);
1153     if(ret < 0) {
1154         xmlSecInternalError("xmlSecBufferInitialize(blob)",
1155                             xmlSecKeyDataKlassGetName(id));
1156         xmlSecBnFinalize(&modulus);
1157         xmlSecBnFinalize(&exponent);
1158         return(-1);
1159     }
1160 
1161     /* read xml */
1162     cur = xmlSecGetNextElementNode(node->children);
1163 
1164     /* first is Modulus node. It is REQUIRED because we do not support Seed and PgenCounter*/
1165     if((cur == NULL) || (!xmlSecCheckNodeName(cur,  xmlSecNodeRSAModulus, xmlSecDSigNs))) {
1166         xmlSecInvalidNodeError(cur, xmlSecNodeRSAModulus,
1167                                xmlSecKeyDataKlassGetName(id));
1168         goto done;
1169     }
1170 
1171     ret = xmlSecBnGetNodeValue(&modulus, cur, xmlSecBnBase64, 1);
1172     if((ret < 0) || (xmlSecBnGetSize(&modulus) == 0)) {
1173         xmlSecInternalError("xmlSecBnGetNodeValue(modulus)",
1174                             xmlSecKeyDataKlassGetName(id));
1175         goto done;
1176     }
1177     cur = xmlSecGetNextElementNode(cur->next);
1178 
1179     /* next is Exponent node. It is REQUIRED because we do not support Seed and PgenCounter*/
1180     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeRSAExponent, xmlSecDSigNs))) {
1181         xmlSecInvalidNodeError(cur, xmlSecNodeRSAExponent, xmlSecKeyDataKlassGetName(id));
1182         goto done;
1183     }
1184     ret = xmlSecBnGetNodeValue(&exponent, cur, xmlSecBnBase64, 1);
1185     if((ret < 0) || (xmlSecBnGetSize(&exponent) == 0)) {
1186         xmlSecInternalError("xmlSecBnGetNodeValue(exponent)",
1187                             xmlSecKeyDataKlassGetName(id));
1188         goto done;
1189     }
1190     cur = xmlSecGetNextElementNode(cur->next);
1191 
1192     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeRSAPrivateExponent, xmlSecNs))) {
1193         /* next is X node. It is REQUIRED for private key but
1194          * MSCrypto does not support it. We just ignore it */
1195         cur = xmlSecGetNextElementNode(cur->next);
1196     }
1197 
1198     if(cur != NULL) {
1199         xmlSecUnexpectedNodeError(cur, xmlSecKeyDataKlassGetName(id));
1200         goto done;
1201     }
1202 
1203     /* Now try to create the key */
1204     blobBufferLen = sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + xmlSecBnGetSize(&modulus);
1205     ret = xmlSecBufferSetSize(&blob, blobBufferLen);
1206     if(ret < 0) {
1207         xmlSecInternalError2("xmlSecBufferSetSize",
1208                              xmlSecKeyDataKlassGetName(id),
1209                              "size=%d", blobBufferLen);
1210         goto done;
1211     }
1212 
1213     /* Set the PUBLICKEYSTRUC */
1214     pubKeyStruc = (PUBLICKEYSTRUC *)xmlSecBufferGetData(&blob);
1215     pubKeyStruc->bType      = PUBLICKEYBLOB;
1216     pubKeyStruc->bVersion   = 0x02;
1217     pubKeyStruc->reserved   = 0;
1218     pubKeyStruc->aiKeyAlg   = CALG_RSA_KEYX | CALG_RSA_SIGN;
1219 
1220     /* Set the public key header */
1221     pubKey = (RSAPUBKEY*) (xmlSecBufferGetData(&blob) + sizeof(PUBLICKEYSTRUC));
1222     pubKey->magic           = 0x31415352;       /* == RSA1 public */
1223     pubKey->bitlen          = xmlSecBnGetSize(&modulus) * 8;    /* Number of bits in prime modulus */
1224     pubKey->pubexp          = 0;
1225     if(sizeof(pubKey->pubexp) < xmlSecBnGetSize(&exponent)) {
1226         xmlSecInvalidSizeLessThanError("exponent size",
1227                 sizeof(pubKey->pubexp), xmlSecBnGetSize(&exponent),
1228                 NULL);
1229         goto done;
1230     }
1231     xmlSecAssert2(xmlSecBnGetData(&exponent) != NULL, -1);
1232     memcpy(&(pubKey->pubexp), xmlSecBnGetData(&exponent), xmlSecBnGetSize(&exponent));
1233 
1234     modulusBlob = (xmlSecByte*) (xmlSecBufferGetData(&blob) + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
1235     xmlSecAssert2(xmlSecBnGetData(&modulus) != NULL, -1);
1236     memcpy(modulusBlob, xmlSecBnGetData(&modulus), xmlSecBnGetSize(&modulus));
1237 
1238     /* Now that we have the blob, import */
1239     hProv = xmlSecMSCryptoFindProvider(xmlSecMSCryptoProviderInfo_Rsa, NULL, CRYPT_VERIFYCONTEXT, TRUE);
1240     if(hProv == 0) {
1241         xmlSecInternalError("xmlSecMSCryptoFindProvider",
1242                             xmlSecKeyDataKlassGetName(id));
1243         goto done;
1244     }
1245 
1246     if (!CryptImportKey(hProv, xmlSecBufferGetData(&blob), xmlSecBufferGetSize(&blob), 0, 0, &hKey)) {
1247         xmlSecMSCryptoError("CryptImportKey",
1248                             xmlSecKeyDataKlassGetName(id));
1249         goto done;
1250     }
1251 
1252     data = xmlSecKeyDataCreate(id);
1253     if(data == NULL ) {
1254         xmlSecInternalError("xmlSecKeyDataCreate",
1255                             xmlSecKeyDataKlassGetName(id));
1256         goto done;
1257     }
1258 
1259     ret = xmlSecMSCryptoKeyDataAdoptKey(data, hProv, TRUE, hKey, 0, xmlSecKeyDataTypePublic);
1260     if(ret < 0) {
1261         xmlSecInternalError("xmlSecMSCryptoKeyDataAdoptKey",
1262                             xmlSecKeyDataKlassGetName(id));
1263         goto done;
1264     }
1265     hProv = 0;
1266     hKey = 0;
1267 
1268     ret = xmlSecKeySetValue(key, data);
1269     if(ret < 0) {
1270         xmlSecInternalError("xmlSecKeySetValue",
1271                             xmlSecKeyDataKlassGetName(id));
1272         xmlSecKeyDataDestroy(data);
1273         goto done;
1274     }
1275     data = NULL;
1276 
1277     /* success */
1278     res = 0;
1279 
1280 done:
1281     if (hProv == 0) {
1282         CryptReleaseContext(hProv, 0);
1283     }
1284     if (hKey != 0) {
1285         CryptDestroyKey(hKey);
1286     }
1287     if (data != 0) {
1288         xmlSecKeyDataDestroy(data);
1289     }
1290 
1291     xmlSecBnFinalize(&modulus);
1292     xmlSecBnFinalize(&exponent);
1293     xmlSecBufferFinalize(&blob);
1294     return(res);
1295 }
1296 
1297 static int
xmlSecMSCryptoKeyDataRsaXmlWrite(xmlSecKeyDataId id,xmlSecKeyPtr key,xmlNodePtr node,xmlSecKeyInfoCtxPtr keyInfoCtx)1298 xmlSecMSCryptoKeyDataRsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
1299                                 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1300     xmlSecMSCryptoKeyDataCtxPtr ctx;
1301     xmlSecBuffer buf;
1302     DWORD dwBlobLen;
1303     xmlSecByte* blob;
1304     PUBLICKEYSTRUC* pubKeyStruc;
1305     RSAPUBKEY *pubKey;
1306     xmlSecSize modulusLen, exponentLen;
1307     xmlNodePtr cur;
1308     int ret;
1309 
1310     xmlSecAssert2(id == xmlSecMSCryptoKeyDataRsaId, -1);
1311     xmlSecAssert2(key != NULL, -1);
1312     xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecMSCryptoKeyDataRsaId), -1);
1313     xmlSecAssert2(node != NULL, -1);
1314     xmlSecAssert2(keyInfoCtx != NULL, -1);
1315 
1316     ctx = xmlSecMSCryptoKeyDataGetCtx(xmlSecKeyGetValue(key));
1317     xmlSecAssert2(ctx != NULL, -1);
1318     xmlSecAssert2(xmlSecMSCryptoKeyDataCtxGetKey(ctx) != 0, -1);
1319 
1320     if (!CryptExportKey(xmlSecMSCryptoKeyDataCtxGetKey(ctx), 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) {
1321         xmlSecMSCryptoError("CryptExportKey",
1322                             xmlSecKeyDataKlassGetName(id));
1323         return(-1);
1324     }
1325 
1326     ret = xmlSecBufferInitialize(&buf, dwBlobLen);
1327     if(ret < 0) {
1328         xmlSecInternalError2("xmlSecBufferInitialize",
1329                              xmlSecKeyDataKlassGetName(id),
1330                              "size=%ld", dwBlobLen);
1331         return(-1);
1332     }
1333 
1334     blob = xmlSecBufferGetData(&buf);
1335     if (!CryptExportKey(xmlSecMSCryptoKeyDataCtxGetKey(ctx), 0, PUBLICKEYBLOB, 0, blob, &dwBlobLen)) {
1336         xmlSecMSCryptoError("CryptExportKey",
1337                             xmlSecKeyDataKlassGetName(id));
1338         xmlSecBufferFinalize(&buf);
1339         return(-1);
1340     }
1341     if (dwBlobLen < sizeof(PUBLICKEYSTRUC)) {
1342         xmlSecInvalidSizeLessThanError("Key blob", dwBlobLen, sizeof(PUBLICKEYSTRUC),
1343                 xmlSecKeyDataKlassGetName(id));
1344         xmlSecBufferFinalize(&buf);
1345         return(-1);
1346     }
1347 
1348     /* check PUBLICKEYSTRUC */
1349     pubKeyStruc = (PUBLICKEYSTRUC*)blob;
1350     if(pubKeyStruc->bVersion != 0x02) {
1351         xmlSecMSCryptoError2("CryptExportKey",
1352                              xmlSecKeyDataKlassGetName(id),
1353                              "pubKeyStruc->bVersion=%ld",
1354                              (long int)pubKeyStruc->bVersion);
1355         xmlSecBufferFinalize(&buf);
1356         return(-1);
1357     }
1358     if(pubKeyStruc->bType != PUBLICKEYBLOB) {
1359         xmlSecMSCryptoError2("CryptExportKey",
1360                              xmlSecKeyDataKlassGetName(id),
1361                              "pubKeyStruc->bType=%ld",
1362                              (long int)pubKeyStruc->bType);
1363         xmlSecBufferFinalize(&buf);
1364         return(-1);
1365     }
1366 
1367     /* check RSAPUBKEY */
1368     pubKey          = (RSAPUBKEY *)(blob + sizeof(PUBLICKEYSTRUC));
1369     if(pubKey->magic != 0x31415352) { /* RSA public key magic */
1370         xmlSecMSCryptoError2("CryptExportKey",
1371                              xmlSecKeyDataKlassGetName(id),
1372                              "pubKey->magic=0x%08lx",
1373                              (long int)pubKey->magic);
1374         xmlSecBufferFinalize(&buf);
1375         return(-1);
1376     }
1377     modulusLen      = pubKey->bitlen / 8;
1378 
1379     if (dwBlobLen < sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + modulusLen) {
1380         xmlSecInvalidSizeLessThanError("Key blob",
1381                 dwBlobLen, sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + modulusLen,
1382                 xmlSecKeyDataKlassGetName(id));
1383         xmlSecBufferFinalize(&buf);
1384         return(-1);
1385     }
1386     blob            += sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY);
1387 
1388     /* first is Modulus node */
1389     cur = xmlSecAddChild(node, xmlSecNodeRSAModulus, xmlSecDSigNs);
1390     if(cur == NULL) {
1391         xmlSecInternalError("xmlSecAddChild(NodeRSAModulus)",
1392                             xmlSecKeyDataKlassGetName(id));
1393         xmlSecBufferFinalize(&buf);
1394         return(-1);
1395     }
1396 
1397     ret = xmlSecBnBlobSetNodeValue(blob, modulusLen, cur, xmlSecBnBase64, 1, 1);
1398     if(ret < 0) {
1399         xmlSecInternalError("xmlSecBnBlobSetNodeValue(NodeRSAModulus)",
1400                             xmlSecKeyDataKlassGetName(id));
1401         xmlSecBufferFinalize(&buf);
1402         return(-1);
1403     }
1404 
1405     /* next is Exponent node. */
1406     cur = xmlSecAddChild(node, xmlSecNodeRSAExponent, xmlSecDSigNs);
1407     if(cur == NULL) {
1408         xmlSecInternalError("xmlSecAddChild(NodeRSAExponent)",
1409                             xmlSecKeyDataKlassGetName(id));
1410         xmlSecBufferFinalize(&buf);
1411         return(-1);
1412     }
1413 
1414     /* Remove leading zero's (from least significant end) */
1415     blob        = (xmlSecByte*)(&(pubKey->pubexp));
1416     exponentLen = sizeof(pubKey->pubexp);
1417     while (exponentLen > 0 && blob[exponentLen - 1] == 0) {
1418         exponentLen--;
1419     }
1420 
1421     ret = xmlSecBnBlobSetNodeValue(blob, exponentLen, cur, xmlSecBnBase64, 1, 1);
1422     if(ret < 0) {
1423         xmlSecInternalError("xmlSecBnBlobSetNodeValue(NodeRSAExponent)",
1424                             xmlSecKeyDataKlassGetName(id));
1425         xmlSecBufferFinalize(&buf);
1426         return(-1);
1427     }
1428 
1429     /* next is PrivateExponent node: not supported in MSCrypto */
1430 
1431     /* done */
1432     xmlSecBufferFinalize(&buf);
1433     return(0);
1434 }
1435 
1436 static int
xmlSecMSCryptoKeyDataRsaGenerate(xmlSecKeyDataPtr data,xmlSecSize sizeBits,xmlSecKeyDataType type ATTRIBUTE_UNUSED)1437 xmlSecMSCryptoKeyDataRsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits,
1438                                 xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
1439     xmlSecMSCryptoKeyDataCtxPtr ctx;
1440     HCRYPTPROV hProv = 0;
1441     HCRYPTKEY hKey = 0;
1442     DWORD dwKeySpec;
1443     DWORD dwSize;
1444     int res = -1;
1445     int ret;
1446 
1447     xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
1448     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), xmlSecKeyDataTypeUnknown);
1449     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataRsaId), -1);
1450     xmlSecAssert2(sizeBits > 0, -1);
1451     UNREFERENCED_PARAMETER(type);
1452 
1453     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
1454     xmlSecAssert2(ctx != NULL, -1);
1455 
1456     /* get provider */
1457     hProv = xmlSecMSCryptoFindProvider(ctx->providers, NULL, CRYPT_VERIFYCONTEXT, TRUE);
1458     if(hProv == 0) {
1459         xmlSecInternalError("xmlSecMSCryptoFindProvider",
1460                             xmlSecKeyDataGetName(data));
1461         goto done;
1462     }
1463 
1464     dwKeySpec = AT_KEYEXCHANGE | AT_SIGNATURE;
1465     dwSize = ((sizeBits << 16) | CRYPT_EXPORTABLE);
1466     if (!CryptGenKey(hProv, CALG_RSA_SIGN, dwSize, &hKey)) {
1467         xmlSecMSCryptoError("CryptGenKey",
1468                             xmlSecKeyDataGetName(data));
1469         goto done;
1470     }
1471 
1472     ret = xmlSecMSCryptoKeyDataAdoptKey(data, hProv, TRUE, hKey, dwKeySpec,
1473                                         xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate);
1474     if(ret < 0) {
1475         xmlSecInternalError("xmlSecMSCryptoKeyDataAdoptKey",
1476                             xmlSecKeyDataGetName(data));
1477         goto done;
1478     }
1479     hProv = 0;
1480     hKey = 0;
1481 
1482     /* success */
1483     res = 0;
1484 
1485 done:
1486     if (hProv != 0) {
1487         CryptReleaseContext(hProv, 0);
1488     }
1489 
1490     if (hKey != 0) {
1491         CryptDestroyKey(hKey);
1492     }
1493 
1494     return(res);
1495 }
1496 
1497 static xmlSecKeyDataType
xmlSecMSCryptoKeyDataRsaGetType(xmlSecKeyDataPtr data)1498 xmlSecMSCryptoKeyDataRsaGetType(xmlSecKeyDataPtr data) {
1499     return(xmlSecMSCryptoKeyDataGetType(data));
1500 }
1501 
1502 static xmlSecSize
xmlSecMSCryptoKeyDataRsaGetSize(xmlSecKeyDataPtr data)1503 xmlSecMSCryptoKeyDataRsaGetSize(xmlSecKeyDataPtr data) {
1504     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataRsaId), 0);
1505 
1506     return (xmlSecMSCryptoKeyDataGetSize(data));
1507 }
1508 
1509 static void
xmlSecMSCryptoKeyDataRsaDebugDump(xmlSecKeyDataPtr data,FILE * output)1510 xmlSecMSCryptoKeyDataRsaDebugDump(xmlSecKeyDataPtr data, FILE* output) {
1511     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataRsaId));
1512     xmlSecAssert(output != NULL);
1513 
1514     fprintf(output, "=== rsa key: size = %d\n",
1515             xmlSecMSCryptoKeyDataRsaGetSize(data));
1516 }
1517 
xmlSecMSCryptoKeyDataRsaDebugXmlDump(xmlSecKeyDataPtr data,FILE * output)1518 static void xmlSecMSCryptoKeyDataRsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
1519     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataRsaId));
1520     xmlSecAssert(output != NULL);
1521 
1522     fprintf(output, "<RSAKeyValue size=\"%d\" />\n",
1523             xmlSecMSCryptoKeyDataRsaGetSize(data));
1524 }
1525 
1526 #endif /* XMLSEC_NO_RSA */
1527 
1528 #ifndef XMLSEC_NO_DSA
1529 /**************************************************************************
1530  *
1531  * <dsig:DSAKeyValue> processing
1532  *
1533  *
1534  * The DSAKeyValue Element (http://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue)
1535  *
1536  * DSA keys and the DSA signature algorithm are specified in [DSS].
1537  * DSA public key values can have the following fields:
1538  *
1539  *   * P - a prime modulus meeting the [DSS] requirements
1540  *   * Q - an integer in the range 2**159 < Q < 2**160 which is a prime
1541  *         divisor of P-1
1542  *   * G - an integer with certain properties with respect to P and Q
1543  *   * Y - G**X mod P (where X is part of the private key and not made
1544  *         public)
1545  *   * J - (P - 1) / Q
1546  *   * seed - a DSA prime generation seed
1547  *   * pgenCounter - a DSA prime generation counter
1548  *
1549  * Parameter J is available for inclusion solely for efficiency as it is
1550  * calculatable from P and Q. Parameters seed and pgenCounter are used in the
1551  * DSA prime number generation algorithm specified in [DSS]. As such, they are
1552  * optional but must either both be present or both be absent. This prime
1553  * generation algorithm is designed to provide assurance that a weak prime is
1554  * not being used and it yields a P and Q value. Parameters P, Q, and G can be
1555  * public and common to a group of users. They might be known from application
1556  * context. As such, they are optional but P and Q must either both appear or
1557  * both be absent. If all of P, Q, seed, and pgenCounter are present,
1558  * implementations are not required to check if they are consistent and are
1559  * free to use either P and Q or seed and pgenCounter. All parameters are
1560  * encoded as base64 [MIME] values.
1561  *
1562  * Arbitrary-length integers (e.g. "bignums" such as RSA moduli) are
1563  * represented in XML as octet strings as defined by the ds:CryptoBinary type.
1564  *
1565  * Schema Definition:
1566  *
1567  * <element name="DSAKeyValue" type="ds:DSAKeyValueType"/>
1568  * <complexType name="DSAKeyValueType">
1569  *   <sequence>
1570  *     <sequence minOccurs="0">
1571  *        <element name="P" type="ds:CryptoBinary"/>
1572  *        <element name="Q" type="ds:CryptoBinary"/>
1573  *     </sequence>
1574  *     <element name="G" type="ds:CryptoBinary" minOccurs="0"/>
1575  *     <element name="Y" type="ds:CryptoBinary"/>
1576  *     <element name="J" type="ds:CryptoBinary" minOccurs="0"/>
1577  *     <sequence minOccurs="0">
1578  *       <element name="Seed" type="ds:CryptoBinary"/>
1579  *       <element name="PgenCounter" type="ds:CryptoBinary"/>
1580  *     </sequence>
1581  *   </sequence>
1582  * </complexType>
1583  *
1584  * DTD Definition:
1585  *
1586  *  <!ELEMENT DSAKeyValue ((P, Q)?, G?, Y, J?, (Seed, PgenCounter)?) >
1587  *  <!ELEMENT P (#PCDATA) >
1588  *  <!ELEMENT Q (#PCDATA) >
1589  *  <!ELEMENT G (#PCDATA) >
1590  *  <!ELEMENT Y (#PCDATA) >
1591  *  <!ELEMENT J (#PCDATA) >
1592  *  <!ELEMENT Seed (#PCDATA) >
1593  *  <!ELEMENT PgenCounter (#PCDATA) >
1594  *
1595  * ============================================================================
1596  *
1597  * To support reading/writing private keys an X element added (before Y).
1598  * todo: The current implementation does not support Seed and PgenCounter!
1599  * by this the P, Q and G are *required*!
1600  *
1601  *************************************************************************/
1602 static int              xmlSecMSCryptoKeyDataDsaInitialize(xmlSecKeyDataPtr data);
1603 static int              xmlSecMSCryptoKeyDataDsaDuplicate(xmlSecKeyDataPtr dst,
1604                                                          xmlSecKeyDataPtr src);
1605 static void             xmlSecMSCryptoKeyDataDsaFinalize(xmlSecKeyDataPtr data);
1606 static int              xmlSecMSCryptoKeyDataDsaXmlRead (xmlSecKeyDataId id,
1607                                                          xmlSecKeyPtr key,
1608                                                          xmlNodePtr node,
1609                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
1610 static int              xmlSecMSCryptoKeyDataDsaXmlWrite(xmlSecKeyDataId id,
1611                                                          xmlSecKeyPtr key,
1612                                                          xmlNodePtr node,
1613                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
1614 static int              xmlSecMSCryptoKeyDataDsaGenerate(xmlSecKeyDataPtr data,
1615                                                          xmlSecSize sizeBits,
1616                                                          xmlSecKeyDataType type);
1617 
1618 static xmlSecKeyDataType xmlSecMSCryptoKeyDataDsaGetType(xmlSecKeyDataPtr data);
1619 static xmlSecSize        xmlSecMSCryptoKeyDataDsaGetSize(xmlSecKeyDataPtr data);
1620 static void              xmlSecMSCryptoKeyDataDsaDebugDump(xmlSecKeyDataPtr data,
1621                                                          FILE* output);
1622 static void             xmlSecMSCryptoKeyDataDsaDebugXmlDump(xmlSecKeyDataPtr data,
1623                                                          FILE* output);
1624 
1625 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataDsaKlass = {
1626     sizeof(xmlSecKeyDataKlass),
1627     xmlSecMSCryptoKeyDataSize,
1628 
1629     /* data */
1630     xmlSecNameDSAKeyValue,
1631     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
1632                                         /* xmlSecKeyDataUsage usage; */
1633     xmlSecHrefDSAKeyValue,              /* const xmlChar* href; */
1634     xmlSecNodeDSAKeyValue,              /* const xmlChar* dataNodeName; */
1635     xmlSecDSigNs,                       /* const xmlChar* dataNodeNs; */
1636 
1637     /* constructors/destructor */
1638     xmlSecMSCryptoKeyDataDsaInitialize, /* xmlSecKeyDataInitializeMethod initialize; */
1639     xmlSecMSCryptoKeyDataDsaDuplicate,  /* xmlSecKeyDataDuplicateMethod duplicate; */
1640     xmlSecMSCryptoKeyDataDsaFinalize,   /* xmlSecKeyDataFinalizeMethod finalize; */
1641     xmlSecMSCryptoKeyDataDsaGenerate,   /* xmlSecKeyDataGenerateMethod generate; */
1642 
1643     /* get info */
1644     xmlSecMSCryptoKeyDataDsaGetType,    /* xmlSecKeyDataGetTypeMethod getType; */
1645     xmlSecMSCryptoKeyDataDsaGetSize,    /* xmlSecKeyDataGetSizeMethod getSize; */
1646     NULL,                               /* xmlSecKeyDataGetIdentifier getIdentifier; */
1647 
1648     /* read/write */
1649     xmlSecMSCryptoKeyDataDsaXmlRead,    /* xmlSecKeyDataXmlReadMethod xmlRead; */
1650     xmlSecMSCryptoKeyDataDsaXmlWrite,   /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
1651     NULL,                               /* xmlSecKeyDataBinReadMethod binRead; */
1652     NULL,                               /* xmlSecKeyDataBinWriteMethod binWrite; */
1653 
1654     /* debug */
1655     xmlSecMSCryptoKeyDataDsaDebugDump,  /* xmlSecKeyDataDebugDumpMethod debugDump; */
1656     xmlSecMSCryptoKeyDataDsaDebugXmlDump,/* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
1657 
1658     /* reserved for the future */
1659     NULL,                               /* void* reserved0; */
1660     NULL,                               /* void* reserved1; */
1661 };
1662 
1663 /* Ordered list of providers to search for algorithm implementation using
1664  * xmlSecMSCryptoFindProvider() function
1665  *
1666  * MUST END with { NULL, 0 } !!!
1667  */
1668 static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Dss[] = {
1669     { MS_DEF_DSS_PROV,              PROV_DSS },
1670     { NULL, 0 }
1671 };
1672 
1673 
1674 /**
1675  * xmlSecMSCryptoKeyDataDsaGetKlass:
1676  *
1677  * The DSA key data klass.
1678  *
1679  * Returns: pointer to DSA key data klass.
1680  */
1681 xmlSecKeyDataId
xmlSecMSCryptoKeyDataDsaGetKlass(void)1682 xmlSecMSCryptoKeyDataDsaGetKlass(void) {
1683     return(&xmlSecMSCryptoKeyDataDsaKlass);
1684 }
1685 
1686 
1687 static int
xmlSecMSCryptoKeyDataDsaInitialize(xmlSecKeyDataPtr data)1688 xmlSecMSCryptoKeyDataDsaInitialize(xmlSecKeyDataPtr data) {
1689     xmlSecMSCryptoKeyDataCtxPtr ctx;
1690     int ret;
1691 
1692     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataDsaId), xmlSecKeyDataTypeUnknown);
1693 
1694     ret = xmlSecMSCryptoKeyDataInitialize(data);
1695     if(ret != 0) {
1696         xmlSecInternalError("xmlSecMSCryptoKeyDataInitialize", NULL);
1697         return(-1);
1698     }
1699 
1700     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
1701     xmlSecAssert2(ctx != NULL, -1);
1702 
1703     ctx->providers = xmlSecMSCryptoProviderInfo_Dss;
1704     return(0);
1705 }
1706 
1707 static int
xmlSecMSCryptoKeyDataDsaDuplicate(xmlSecKeyDataPtr dst,xmlSecKeyDataPtr src)1708 xmlSecMSCryptoKeyDataDsaDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
1709     xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecMSCryptoKeyDataDsaId), -1);
1710     xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecMSCryptoKeyDataDsaId), -1);
1711 
1712     return(xmlSecMSCryptoKeyDataDuplicate(dst, src));
1713 }
1714 
1715 static void
xmlSecMSCryptoKeyDataDsaFinalize(xmlSecKeyDataPtr data)1716 xmlSecMSCryptoKeyDataDsaFinalize(xmlSecKeyDataPtr data) {
1717     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataDsaId));
1718 
1719     xmlSecMSCryptoKeyDataFinalize(data);
1720 }
1721 
1722 static int
xmlSecMSCryptoKeyDataDsaXmlRead(xmlSecKeyDataId id,xmlSecKeyPtr key,xmlNodePtr node,xmlSecKeyInfoCtxPtr keyInfoCtx)1723 xmlSecMSCryptoKeyDataDsaXmlRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
1724                            xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
1725     xmlSecKeyDataPtr data = NULL;
1726     xmlNodePtr cur;
1727     xmlSecBn p, q, g, y;
1728     xmlSecBuffer blob;
1729     unsigned int blobBufferLen;
1730     PUBLICKEYSTRUC *pubKeyStruc = NULL;
1731     DSSPUBKEY *pubKey = NULL;
1732     DSSSEED* seed = NULL;
1733     BYTE *buf = NULL;
1734     HCRYPTPROV hProv = 0;
1735     HCRYPTKEY hKey = 0;
1736     xmlSecSize i;
1737     int res = -1;
1738     int ret;
1739 
1740     xmlSecAssert2(id == xmlSecMSCryptoKeyDataDsaId, -1);
1741     xmlSecAssert2(key != NULL, -1);
1742     xmlSecAssert2(node != NULL, -1);
1743     xmlSecAssert2(keyInfoCtx != NULL, -1);
1744 
1745     if(xmlSecKeyGetValue(key) != NULL) {
1746         xmlSecOtherError(XMLSEC_ERRORS_R_INVALID_KEY_DATA,
1747                          xmlSecKeyDataKlassGetName(id),
1748                          "key already has a value");
1749         return(-1);
1750     }
1751 
1752     /* initialize buffers */
1753     ret = xmlSecBnInitialize(&p, 0);
1754     if(ret < 0) {
1755         xmlSecInternalError("xmlSecBnInitialize(p)",
1756                             xmlSecKeyDataKlassGetName(id));
1757         return(-1);
1758     }
1759 
1760     ret = xmlSecBnInitialize(&q, 0);
1761     if(ret < 0) {
1762         xmlSecInternalError("xmlSecBnInitialize(q)",
1763                             xmlSecKeyDataKlassGetName(id));
1764         xmlSecBnFinalize(&p);
1765         return(-1);
1766     }
1767 
1768     ret = xmlSecBnInitialize(&g, 0);
1769     if(ret < 0) {
1770         xmlSecInternalError("xmlSecBnInitialize(g)",
1771                             xmlSecKeyDataKlassGetName(id));
1772         xmlSecBnFinalize(&p);
1773         xmlSecBnFinalize(&q);
1774         return(-1);
1775     }
1776 
1777     ret = xmlSecBnInitialize(&y, 0);
1778     if(ret < 0) {
1779         xmlSecInternalError("xmlSecBnInitialize(y)",
1780                             xmlSecKeyDataKlassGetName(id));
1781         xmlSecBnFinalize(&p);
1782         xmlSecBnFinalize(&q);
1783         xmlSecBnFinalize(&g);
1784         return(-1);
1785     }
1786 
1787     ret = xmlSecBufferInitialize(&blob, 0);
1788     if(ret < 0) {
1789         xmlSecInternalError("xmlSecBufferInitialize(blob)",
1790                             xmlSecKeyDataKlassGetName(id));
1791         xmlSecBnFinalize(&p);
1792         xmlSecBnFinalize(&q);
1793         xmlSecBnFinalize(&g);
1794         xmlSecBnFinalize(&y);
1795         return(-1);
1796     }
1797 
1798     /* read xml */
1799     cur = xmlSecGetNextElementNode(node->children);
1800 
1801     /* first is P node. It is REQUIRED because we do not support Seed and PgenCounter*/
1802     if((cur == NULL) || (!xmlSecCheckNodeName(cur,  xmlSecNodeDSAP, xmlSecDSigNs))) {
1803         xmlSecInvalidNodeError(cur, xmlSecNodeDSAP, xmlSecKeyDataKlassGetName(id));
1804         goto done;
1805     }
1806 
1807     ret = xmlSecBnGetNodeValue(&p, cur, xmlSecBnBase64, 1);
1808     if((ret < 0) || (xmlSecBnGetSize(&p) == 0)) {
1809         xmlSecInternalError("xmlSecBnGetNodeValue(p)",
1810                             xmlSecKeyDataKlassGetName(id));
1811         goto done;
1812     }
1813     cur = xmlSecGetNextElementNode(cur->next);
1814 
1815     /* next is Q node. It is REQUIRED because we do not support Seed and PgenCounter*/
1816     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAQ, xmlSecDSigNs))) {
1817         xmlSecInvalidNodeError(cur, xmlSecNodeDSAQ, xmlSecKeyDataKlassGetName(id));
1818         goto done;
1819     }
1820     ret = xmlSecBnGetNodeValue(&q, cur, xmlSecBnBase64, 1);
1821     if((ret < 0) || (xmlSecBnGetSize(&q) == 0)) {
1822         xmlSecInternalError("xmlSecBnGetNodeValue(q)",
1823                             xmlSecKeyDataKlassGetName(id));
1824         goto done;
1825     }
1826     cur = xmlSecGetNextElementNode(cur->next);
1827 
1828     /* next is G node. It is REQUIRED because we do not support Seed and PgenCounter*/
1829     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAG, xmlSecDSigNs))) {
1830         xmlSecInvalidNodeError(cur, xmlSecNodeDSAG, xmlSecKeyDataKlassGetName(id));
1831         goto done;
1832     }
1833     ret = xmlSecBnGetNodeValue(&g, cur, xmlSecBnBase64, 1);
1834     if((ret < 0) || (xmlSecBnGetSize(&q) == 0)) {
1835         xmlSecInternalError("xmlSecBnGetNodeValue(g)",
1836                             xmlSecKeyDataKlassGetName(id));
1837         goto done;
1838     }
1839     cur = xmlSecGetNextElementNode(cur->next);
1840 
1841     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAX, xmlSecNs))) {
1842         /* next is X node. It is REQUIRED for private key but
1843          * MSCrypto does not support it, we just ignore it */
1844 
1845         cur = xmlSecGetNextElementNode(cur->next);
1846     }
1847 
1848     /* next is Y node. */
1849     if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeDSAY, xmlSecDSigNs))) {
1850         xmlSecInvalidNodeError(cur, xmlSecNodeDSAY, xmlSecKeyDataKlassGetName(id));
1851         goto done;
1852     }
1853     ret = xmlSecBnGetNodeValue(&y, cur, xmlSecBnBase64, 1);
1854     if((ret < 0) || (xmlSecBnGetSize(&y) == 0)) {
1855         xmlSecInternalError("xmlSecBnGetNodeValue(y)",
1856                             xmlSecKeyDataKlassGetName(id));
1857         goto done;
1858     }
1859     cur = xmlSecGetNextElementNode(cur->next);
1860 
1861     /* todo: add support for J */
1862     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAJ, xmlSecDSigNs))) {
1863         cur = xmlSecGetNextElementNode(cur->next);
1864     }
1865 
1866     /* todo: add support for seed */
1867     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSASeed, xmlSecDSigNs))) {
1868         cur = xmlSecGetNextElementNode(cur->next);
1869     }
1870 
1871     /* todo: add support for pgencounter */
1872     if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDSAPgenCounter, xmlSecDSigNs))) {
1873         cur = xmlSecGetNextElementNode(cur->next);
1874     }
1875 
1876     if(cur != NULL) {
1877         xmlSecUnexpectedNodeError(cur, xmlSecKeyDataKlassGetName(id))
1878         goto done;
1879     }
1880 
1881     /* we assume that sizeof(q) < 0x14, sizeof(g) <= sizeof(p) and sizeof(y) <= sizeof(p) */
1882     blobBufferLen = sizeof(PUBLICKEYSTRUC) + sizeof(DSSPUBKEY) + 3 * xmlSecBnGetSize(&p) + 0x14 + sizeof(DSSSEED);
1883     ret = xmlSecBufferSetSize(&blob, blobBufferLen);
1884     if(ret < 0) {
1885         xmlSecInternalError2("xmlSecBufferSetSize", NULL, "size=%d", blobBufferLen);
1886         goto done;
1887     }
1888 
1889     /* Set PUBLICKEYSTRUC  */
1890     pubKeyStruc             = (PUBLICKEYSTRUC *)xmlSecBufferGetData(&blob);
1891     pubKeyStruc->bType      = PUBLICKEYBLOB;
1892     pubKeyStruc->bVersion   = 0x02;
1893     pubKeyStruc->reserved   = 0;
1894     pubKeyStruc->aiKeyAlg   = CALG_DSS_SIGN;
1895 
1896     /* Set the public key header */
1897     pubKey                  = (DSSPUBKEY *) (xmlSecBufferGetData(&blob) + sizeof(PUBLICKEYSTRUC));
1898     pubKey->magic           = 0x31535344;       /* == DSS1 pub key */
1899     pubKey->bitlen          = xmlSecBnGetSize(&p) * 8; /* Number of bits in prime modulus */
1900 
1901     /* copy the key data */
1902     buf                     = (BYTE*) (xmlSecBufferGetData(&blob) + sizeof(PUBLICKEYSTRUC) + sizeof(DSSPUBKEY));
1903 
1904     /* set p */
1905     xmlSecAssert2(xmlSecBnGetData(&p) != NULL, -1);
1906     memcpy(buf, xmlSecBnGetData(&p), xmlSecBnGetSize(&p));
1907     buf += xmlSecBnGetSize(&p);
1908 
1909     /* set q */
1910     if(xmlSecBnGetSize(&q) > 0x14) {
1911         xmlSecInvalidSizeLessThanError("DSA key q",
1912                                        xmlSecBnGetSize(&q), 0x14, NULL);
1913         goto done;
1914     }
1915     xmlSecAssert2(xmlSecBnGetData(&q) != NULL, -1);
1916     memcpy(buf, xmlSecBnGetData(&q), xmlSecBnGetSize(&q));
1917     buf += xmlSecBnGetSize(&q);
1918 
1919     /* Pad with zeros */
1920     for(i = xmlSecBnGetSize(&q); i < 0x14; ++i) {
1921         *(buf++) = 0;
1922     }
1923 
1924     /* set generator */
1925     if(xmlSecBnGetSize(&g) > xmlSecBnGetSize(&p)) {
1926         xmlSecInvalidSizeMoreThanError("DSA key g",
1927                                        xmlSecBnGetSize(&g),
1928                                        xmlSecBnGetSize(&p),
1929                                        NULL);
1930         goto done;
1931     }
1932     xmlSecAssert2(xmlSecBnGetData(&g) != NULL, -1);
1933     memcpy(buf, xmlSecBnGetData(&g), xmlSecBnGetSize(&g));
1934     buf += xmlSecBnGetSize(&g);
1935     /* Pad with zeros */
1936     for(i = xmlSecBnGetSize(&g); i < xmlSecBnGetSize(&p); ++i) {
1937         *(buf++) = 0;
1938     }
1939 
1940     /* Public key */
1941     if(xmlSecBnGetSize(&y) > xmlSecBnGetSize(&p)) {
1942         xmlSecInvalidSizeMoreThanError("DSA key y",
1943                                        xmlSecBnGetSize(&y),
1944                                        xmlSecBnGetSize(&p),
1945                                        NULL);
1946         goto done;
1947     }
1948     xmlSecAssert2(xmlSecBnGetData(&y) != NULL, -1);
1949     memcpy(buf, xmlSecBnGetData(&y), xmlSecBnGetSize(&y));
1950     buf += xmlSecBnGetSize(&y);
1951     /* Pad with zeros */
1952     for(i = xmlSecBnGetSize(&y); i < xmlSecBnGetSize(&p); ++i) {
1953         *(buf++) = 0;
1954     }
1955 
1956     /* Set seed to 0xFFFFFFFFF */
1957     seed = (DSSSEED*)buf;
1958     memset(seed, 0, sizeof(*seed));
1959     seed->counter = 0xFFFFFFFF; /* SEED Counter set to 0xFFFFFFFF will cause seed to be ignored */
1960 
1961     hProv = xmlSecMSCryptoFindProvider(xmlSecMSCryptoProviderInfo_Dss, NULL, CRYPT_VERIFYCONTEXT, TRUE);
1962     if(hProv == 0) {
1963         xmlSecInternalError("xmlSecMSCryptoFindProvider",
1964                             xmlSecKeyDataKlassGetName(id));
1965         goto done;
1966     }
1967 
1968     /* import the key blob */
1969     if (!CryptImportKey(hProv, xmlSecBufferGetData(&blob), xmlSecBufferGetSize(&blob), 0, 0, &hKey)) {
1970         xmlSecMSCryptoError("CryptImportKey",
1971                             xmlSecKeyDataKlassGetName(id));
1972         goto done;
1973     }
1974 
1975     data = xmlSecKeyDataCreate(id);
1976     if(data == NULL ) {
1977         xmlSecInternalError("xmlSecKeyDataCreate",
1978                             xmlSecKeyDataKlassGetName(id));
1979         goto done;
1980     }
1981 
1982     ret = xmlSecMSCryptoKeyDataAdoptKey(data, hProv, TRUE, hKey, 0, xmlSecKeyDataTypePublic);
1983     if(ret < 0) {
1984         xmlSecInternalError("xmlSecMSCryptoKeyDataAdoptKey",
1985                             xmlSecKeyDataGetName(data));
1986         goto done;
1987     }
1988     hProv = 0;
1989     hKey = 0;
1990 
1991     ret = xmlSecKeySetValue(key, data);
1992     if(ret < 0) {
1993         xmlSecInternalError("xmlSecKeySetValue",
1994                             xmlSecKeyDataGetName(data));
1995         goto done;
1996     }
1997     data = NULL;
1998 
1999     /* success */
2000     res = 0;
2001 
2002 done:
2003     if (hKey != 0) {
2004         CryptDestroyKey(hKey);
2005     }
2006     if (hProv != 0) {
2007         CryptReleaseContext(hProv, 0);
2008     }
2009     if (data != NULL) {
2010         xmlSecKeyDataDestroy(data);
2011     }
2012 
2013     xmlSecBufferFinalize(&blob);
2014     xmlSecBnFinalize(&p);
2015     xmlSecBnFinalize(&q);
2016     xmlSecBnFinalize(&g);
2017     xmlSecBnFinalize(&y);
2018 
2019     return(res);
2020 }
2021 
2022 static int
xmlSecMSCryptoKeyDataDsaXmlWrite(xmlSecKeyDataId id,xmlSecKeyPtr key,xmlNodePtr node,xmlSecKeyInfoCtxPtr keyInfoCtx)2023 xmlSecMSCryptoKeyDataDsaXmlWrite(xmlSecKeyDataId id, xmlSecKeyPtr key,
2024                                 xmlNodePtr node, xmlSecKeyInfoCtxPtr keyInfoCtx) {
2025     xmlSecMSCryptoKeyDataCtxPtr ctx;
2026     xmlSecBuffer buf;
2027     DWORD dwBlobLen;
2028     xmlSecByte* blob;
2029     PUBLICKEYSTRUC* pubKeyStruc;
2030     DSSPUBKEY *pubKey;
2031     xmlSecSize keyLen, len;
2032     xmlNodePtr cur;
2033     int ret;
2034 
2035 
2036     xmlSecAssert2(id == xmlSecMSCryptoKeyDataDsaId, -1);
2037     xmlSecAssert2(key != NULL, -1);
2038     xmlSecAssert2(xmlSecKeyDataCheckId(xmlSecKeyGetValue(key), xmlSecMSCryptoKeyDataDsaId), -1);
2039     xmlSecAssert2(node != NULL, -1);
2040     xmlSecAssert2(keyInfoCtx != NULL, -1);
2041 
2042     ctx = xmlSecMSCryptoKeyDataGetCtx(xmlSecKeyGetValue(key));
2043     xmlSecAssert2(ctx != NULL, -1);
2044     xmlSecAssert2(xmlSecMSCryptoKeyDataCtxGetKey(ctx) != 0, -1);
2045 
2046     if (!CryptExportKey(xmlSecMSCryptoKeyDataCtxGetKey(ctx), 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) {
2047         xmlSecInternalError("CryptExportKey",
2048                             xmlSecKeyDataKlassGetName(id));
2049         return(-1);
2050     }
2051 
2052     ret = xmlSecBufferInitialize(&buf, dwBlobLen);
2053     if(ret < 0) {
2054         xmlSecInternalError2("xmlSecBufferInitialize",
2055                              xmlSecKeyDataKlassGetName(id),
2056                              "size=%ld", dwBlobLen);
2057         return(-1);
2058     }
2059 
2060     blob = xmlSecBufferGetData(&buf);
2061     if (!CryptExportKey(xmlSecMSCryptoKeyDataCtxGetKey(ctx), 0, PUBLICKEYBLOB, 0, blob, &dwBlobLen)) {
2062         xmlSecMSCryptoError("CryptExportKey",
2063                             xmlSecKeyDataKlassGetName(id));
2064         xmlSecBufferFinalize(&buf);
2065         return(-1);
2066     }
2067     if (dwBlobLen < sizeof(PUBLICKEYSTRUC)) {
2068         xmlSecInvalidSizeLessThanError("Key blob", dwBlobLen, sizeof(PUBLICKEYSTRUC),
2069                 xmlSecKeyDataKlassGetName(id));
2070         xmlSecBufferFinalize(&buf);
2071         return(-1);
2072     }
2073 
2074     /* check PUBLICKEYSTRUC */
2075     pubKeyStruc     = (PUBLICKEYSTRUC*)blob;
2076     if(pubKeyStruc->bVersion != 0x02) {
2077         xmlSecMSCryptoError2("CryptExportKey",
2078                              xmlSecKeyDataKlassGetName(id),
2079                              "pubKeyStruc->bVersion=%ld",
2080                              (long int)pubKeyStruc->bVersion);
2081         xmlSecBufferFinalize(&buf);
2082         return(-1);
2083     }
2084     if(pubKeyStruc->bType != PUBLICKEYBLOB) {
2085         xmlSecMSCryptoError2("CryptExportKey",
2086                              xmlSecKeyDataKlassGetName(id),
2087                              "pubKeyStruc->bType=%ld",
2088                              (long int)pubKeyStruc->bType);
2089         xmlSecBufferFinalize(&buf);
2090         return(-1);
2091     }
2092 
2093     /* check DSSPUBKEY */
2094     pubKey          = (DSSPUBKEY*)(blob + sizeof(PUBLICKEYSTRUC));
2095     if(pubKey->magic != 0x31535344) { /* DSS key magic */
2096         xmlSecMSCryptoError2("CryptExportKey",
2097                              xmlSecKeyDataKlassGetName(id),
2098                              "pubKey->magic=0x%08lx",
2099                              (long int)pubKey->magic);
2100         xmlSecBufferFinalize(&buf);
2101         return(-1);
2102     }
2103     keyLen          = pubKey->bitlen / 8;
2104 
2105     /* we assume that sizeof(q) < 0x14, sizeof(g) <= sizeof(p) and sizeof(y) <= sizeof(p) */
2106     if (dwBlobLen < sizeof(PUBLICKEYSTRUC) + sizeof(DSSPUBKEY) + 3 * keyLen + 0x14 + sizeof(DSSSEED)) {
2107         xmlSecInvalidSizeLessThanError("Key blob",
2108                 dwBlobLen, sizeof(PUBLICKEYSTRUC) + sizeof(DSSPUBKEY) + 3 * keyLen + 0x14 + sizeof(DSSSEED),
2109                 xmlSecKeyDataKlassGetName(id));
2110         xmlSecBufferFinalize(&buf);
2111         return(-1);
2112     }
2113     blob            += sizeof(PUBLICKEYSTRUC) + sizeof(DSSPUBKEY);
2114 
2115     /* first is P node */
2116     cur = xmlSecAddChild(node, xmlSecNodeDSAP, xmlSecDSigNs);
2117     if(cur == NULL) {
2118         xmlSecInternalError("xmlSecAddChild(NodeDSAP)",
2119                             xmlSecKeyDataKlassGetName(id));
2120         xmlSecBufferFinalize(&buf);
2121         return(-1);
2122     }
2123 
2124     ret = xmlSecBnBlobSetNodeValue(blob, keyLen, cur, xmlSecBnBase64, 1, 1);
2125     if(ret < 0) {
2126         xmlSecInternalError("xmlSecBnBlobSetNodeValue(NodeDSAP)",
2127                             xmlSecKeyDataKlassGetName(id));
2128         xmlSecBufferFinalize(&buf);
2129         return(-1);
2130     }
2131     blob += keyLen;
2132 
2133     /* next is Q node. */
2134     cur = xmlSecAddChild(node, xmlSecNodeDSAQ, xmlSecDSigNs);
2135     if(cur == NULL) {
2136         xmlSecInternalError("xmlSecAddChild(NodeDSAQ)",
2137                             xmlSecKeyDataKlassGetName(id));
2138         xmlSecBufferFinalize(&buf);
2139         return(-1);
2140     }
2141 
2142     /* we think that the size of q is 0x14, skip trailing zeros */
2143     for(len = 0x14; len > 0 && blob[len - 1] == 0; --len);
2144 
2145     ret = xmlSecBnBlobSetNodeValue(blob, len, cur, xmlSecBnBase64, 1, 1);
2146     if(ret < 0) {
2147         xmlSecInternalError("xmlSecBnBlobSetNodeValue(NodeDSAQ)",
2148                             xmlSecKeyDataKlassGetName(id));
2149         xmlSecBufferFinalize(&buf);
2150         return(-1);
2151     }
2152     blob += 0x14;
2153 
2154     /* next is G node. */
2155     cur = xmlSecAddChild(node, xmlSecNodeDSAG, xmlSecDSigNs);
2156     if(cur == NULL) {
2157         xmlSecInternalError("xmlSecAddChild(NodeDSAG)",
2158                             xmlSecKeyDataKlassGetName(id));
2159         xmlSecBufferFinalize(&buf);
2160         return(-1);
2161     }
2162 
2163     /* skip trailing zeros */
2164     for(len = keyLen; len > 0 && blob[len - 1] == 0; --len);
2165 
2166     ret = xmlSecBnBlobSetNodeValue(blob, len, cur, xmlSecBnBase64, 1, 1);
2167     if(ret < 0) {
2168         xmlSecInternalError("xmlSecBnBlobSetNodeValue(NodeDSAG)",
2169                             xmlSecKeyDataKlassGetName(id));
2170         xmlSecBufferFinalize(&buf);
2171         return(-1);
2172     }
2173     blob += keyLen;
2174 
2175     /* next is X node: not supported in MSCrypto */
2176 
2177     /* next is Y node. */
2178     cur = xmlSecAddChild(node, xmlSecNodeDSAY, xmlSecDSigNs);
2179     if(cur == NULL) {
2180         xmlSecInternalError("xmlSecAddChild(NodeDSAY)",
2181                             xmlSecKeyDataKlassGetName(id));
2182         xmlSecBufferFinalize(&buf);
2183         return(-1);
2184     }
2185 
2186     /* skip trailing zeros */
2187     for(len = keyLen; len > 0 && blob[len - 1] == 0; --len);
2188 
2189     ret = xmlSecBnBlobSetNodeValue(blob, len, cur, xmlSecBnBase64, 1, 1);
2190     if(ret < 0) {
2191         xmlSecInternalError("xmlSecBnBlobSetNodeValue(NodeDSAY)",
2192                             xmlSecKeyDataKlassGetName(id));
2193         xmlSecBufferFinalize(&buf);
2194         return(-1);
2195     }
2196     blob += keyLen;
2197 
2198     xmlSecBufferFinalize(&buf);
2199     return(0);
2200 }
2201 
2202 static int
xmlSecMSCryptoKeyDataDsaGenerate(xmlSecKeyDataPtr data,xmlSecSize sizeBits,xmlSecKeyDataType type ATTRIBUTE_UNUSED)2203 xmlSecMSCryptoKeyDataDsaGenerate(xmlSecKeyDataPtr data, xmlSecSize sizeBits, xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
2204     xmlSecMSCryptoKeyDataCtxPtr ctx;
2205     HCRYPTPROV hProv = 0;
2206     HCRYPTKEY hKey = 0;
2207     DWORD dwKeySpec;
2208     DWORD dwSize;
2209     int res = -1;
2210     int ret;
2211 
2212     xmlSecAssert2(xmlSecKeyDataIsValid(data), xmlSecKeyDataTypeUnknown);
2213     xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), xmlSecKeyDataTypeUnknown);
2214     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataDsaId), -1);
2215     xmlSecAssert2(sizeBits > 0, -1);
2216     UNREFERENCED_PARAMETER(type);
2217 
2218     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
2219 
2220     hProv = xmlSecMSCryptoFindProvider(ctx->providers, NULL, CRYPT_VERIFYCONTEXT, TRUE);
2221     if(hProv == 0) {
2222         xmlSecInternalError("xmlSecMSCryptoFindProvider",
2223                             xmlSecKeyDataGetName(data));
2224         return(-1);
2225     }
2226 
2227     dwKeySpec = AT_SIGNATURE;
2228     dwSize = ((sizeBits << 16) | CRYPT_EXPORTABLE);
2229     if (!CryptGenKey(hProv, CALG_DSS_SIGN, dwSize, &hKey)) {
2230             xmlSecMSCryptoError("CryptGenKey",
2231                                 xmlSecKeyDataGetName(data));
2232             goto done;
2233     }
2234 
2235     ret = xmlSecMSCryptoKeyDataAdoptKey(data, hProv, TRUE, hKey, dwKeySpec,
2236         xmlSecKeyDataTypePublic | xmlSecKeyDataTypePrivate);
2237     if(ret < 0) {
2238             xmlSecInternalError("xmlSecMSCryptoKeyDataAdoptKey",
2239                                 xmlSecKeyDataGetName(data));
2240             goto done;
2241     }
2242     hProv = 0;
2243     hKey = 0;
2244 
2245     /* success */
2246     res = 0;
2247 
2248 done:
2249     if (hProv != 0) {
2250         CryptReleaseContext(hProv, 0);
2251     }
2252 
2253     if (hKey != 0) {
2254             CryptDestroyKey(hKey);
2255     }
2256 
2257     return(res);
2258 }
2259 
2260 static xmlSecKeyDataType
xmlSecMSCryptoKeyDataDsaGetType(xmlSecKeyDataPtr data)2261 xmlSecMSCryptoKeyDataDsaGetType(xmlSecKeyDataPtr data) {
2262     return(xmlSecMSCryptoKeyDataGetType(data));
2263 }
2264 
2265 static xmlSecSize
xmlSecMSCryptoKeyDataDsaGetSize(xmlSecKeyDataPtr data)2266 xmlSecMSCryptoKeyDataDsaGetSize(xmlSecKeyDataPtr data) {
2267     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataDsaId), 0);
2268 
2269     return xmlSecMSCryptoKeyDataGetSize(data);
2270 }
2271 
2272 static void
xmlSecMSCryptoKeyDataDsaDebugDump(xmlSecKeyDataPtr data,FILE * output)2273 xmlSecMSCryptoKeyDataDsaDebugDump(xmlSecKeyDataPtr data, FILE* output) {
2274     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataDsaId));
2275     xmlSecAssert(output != NULL);
2276 
2277     fprintf(output, "=== dsa key: size = %d\n",
2278             xmlSecMSCryptoKeyDataDsaGetSize(data));
2279 }
2280 
2281 static void
xmlSecMSCryptoKeyDataDsaDebugXmlDump(xmlSecKeyDataPtr data,FILE * output)2282 xmlSecMSCryptoKeyDataDsaDebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
2283     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataDsaId));
2284     xmlSecAssert(output != NULL);
2285 
2286     fprintf(output, "<DSAKeyValue size=\"%d\" />\n",
2287             xmlSecMSCryptoKeyDataDsaGetSize(data));
2288 }
2289 
2290 #endif /* XMLSEC_NO_DSA */
2291 
2292 
2293 #ifndef XMLSEC_NO_GOST
2294 /**************************************************************************
2295  *
2296  * GOST2001 xml key representation processing. Contain errors.
2297  *
2298  *************************************************************************/
2299 static int              xmlSecMSCryptoKeyDataGost2001Initialize(xmlSecKeyDataPtr data);
2300 static int              xmlSecMSCryptoKeyDataGost2001Duplicate(xmlSecKeyDataPtr dst,
2301                                                          xmlSecKeyDataPtr src);
2302 static void             xmlSecMSCryptoKeyDataGost2001Finalize(xmlSecKeyDataPtr data);
2303 static int              xmlSecMSCryptoKeyDataGost2001XmlRead    (xmlSecKeyDataId id,
2304                                                          xmlSecKeyPtr key,
2305                                                          xmlNodePtr node,
2306                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
2307 static int              xmlSecMSCryptoKeyDataGost2001XmlWrite(xmlSecKeyDataId id,
2308                                                          xmlSecKeyPtr key,
2309                                                          xmlNodePtr node,
2310                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
2311 static int              xmlSecMSCryptoKeyDataGost2001Generate(xmlSecKeyDataPtr data,
2312                                                          xmlSecSize sizeBits,
2313                                                          xmlSecKeyDataType type);
2314 
2315 static xmlSecKeyDataType xmlSecMSCryptoKeyDataGost2001GetType(xmlSecKeyDataPtr data);
2316 static xmlSecSize        xmlSecMSCryptoKeyDataGost2001GetSize(xmlSecKeyDataPtr data);
2317 static void              xmlSecMSCryptoKeyDataGost2001DebugDump(xmlSecKeyDataPtr data,
2318                                                          FILE* output);
2319 static void             xmlSecMSCryptoKeyDataGost2001DebugXmlDump(xmlSecKeyDataPtr data,
2320                                                          FILE* output);
2321 
2322 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataGost2001Klass = {
2323     sizeof(xmlSecKeyDataKlass),
2324     xmlSecMSCryptoKeyDataSize,
2325 
2326     /* data */
2327     xmlSecNameGOST2001KeyValue,
2328     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
2329                                         /* xmlSecKeyDataUsage usage; */
2330     xmlSecHrefGOST2001KeyValue,         /* const xmlChar* href; */
2331     xmlSecNodeGOST2001KeyValue,         /* const xmlChar* dataNodeName; */
2332     xmlSecDSigNs,                       /* const xmlChar* dataNodeNs; */
2333 
2334     /* constructors/destructor */
2335     xmlSecMSCryptoKeyDataGost2001Initialize,    /* xmlSecKeyDataInitializeMethod initialize; */
2336     xmlSecMSCryptoKeyDataGost2001Duplicate,     /* xmlSecKeyDataDuplicateMethod duplicate; */
2337     xmlSecMSCryptoKeyDataGost2001Finalize,      /* xmlSecKeyDataFinalizeMethod finalize; */
2338     NULL, /* xmlSecMSCryptoKeyDataGost2001Generate,*/   /* xmlSecKeyDataGenerateMethod generate; */
2339 
2340     /* get info */
2341     xmlSecMSCryptoKeyDataGost2001GetType,       /* xmlSecKeyDataGetTypeMethod getType; */
2342     xmlSecMSCryptoKeyDataGost2001GetSize,       /* xmlSecKeyDataGetSizeMethod getSize; */
2343     NULL,                               /* xmlSecKeyDataGetIdentifier getIdentifier; */
2344 
2345     /* read/write */
2346     NULL,       /* xmlSecKeyDataXmlReadMethod xmlRead; */
2347     NULL,       /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
2348     NULL,                               /* xmlSecKeyDataBinReadMethod binRead; */
2349     NULL,                               /* xmlSecKeyDataBinWriteMethod binWrite; */
2350 
2351     /* debug */
2352     xmlSecMSCryptoKeyDataGost2001DebugDump,     /* xmlSecKeyDataDebugDumpMethod debugDump; */
2353     xmlSecMSCryptoKeyDataGost2001DebugXmlDump,/* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
2354 
2355     /* reserved for the future */
2356     NULL,                               /* void* reserved0; */
2357     NULL,                               /* void* reserved1; */
2358 };
2359 
2360 /* Ordered list of providers to search for algorithm implementation using
2361  * xmlSecMSCryptoFindProvider() function
2362  *
2363  * MUST END with { NULL, 0 } !!!
2364  */
2365 static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Gost[] = {
2366     { MAGPRO_CSP,                   PROV_MAGPRO_GOST },
2367     { CRYPTOPRO_CSP,                PROV_CRYPTOPRO_GOST },
2368     { NULL, 0 }
2369 };
2370 
2371 /**
2372  * xmlSecMSCryptoKeyDataGost2001GetKlass:
2373  *
2374  * The GOST2001 key data klass.
2375  *
2376  * Returns: pointer to GOST2001 key data klass.
2377  */
2378 xmlSecKeyDataId
xmlSecMSCryptoKeyDataGost2001GetKlass(void)2379 xmlSecMSCryptoKeyDataGost2001GetKlass(void) {
2380     return(&xmlSecMSCryptoKeyDataGost2001Klass);
2381 }
2382 
2383 
2384 static int
xmlSecMSCryptoKeyDataGost2001Initialize(xmlSecKeyDataPtr data)2385 xmlSecMSCryptoKeyDataGost2001Initialize(xmlSecKeyDataPtr data) {
2386     xmlSecMSCryptoKeyDataCtxPtr ctx;
2387     int ret;
2388 
2389     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id), xmlSecKeyDataTypeUnknown);
2390 
2391     ret = xmlSecMSCryptoKeyDataInitialize(data);
2392     if(ret != 0) {
2393         xmlSecInternalError("xmlSecMSCryptoKeyDataInitialize", NULL);
2394         return(-1);
2395     }
2396 
2397     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
2398     xmlSecAssert2(ctx != NULL, -1);
2399 
2400     ctx->providers = xmlSecMSCryptoProviderInfo_Gost;
2401     return(0);
2402 }
2403 
2404 static int
xmlSecMSCryptoKeyDataGost2001Duplicate(xmlSecKeyDataPtr dst,xmlSecKeyDataPtr src)2405 xmlSecMSCryptoKeyDataGost2001Duplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
2406     xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecMSCryptoKeyDataGost2001Id), -1);
2407     xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecMSCryptoKeyDataGost2001Id), -1);
2408 
2409     return(xmlSecMSCryptoKeyDataDuplicate(dst, src));
2410 }
2411 
2412 static void
xmlSecMSCryptoKeyDataGost2001Finalize(xmlSecKeyDataPtr data)2413 xmlSecMSCryptoKeyDataGost2001Finalize(xmlSecKeyDataPtr data) {
2414     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id));
2415 
2416     xmlSecMSCryptoKeyDataFinalize(data);
2417 }
2418 
2419 static xmlSecKeyDataType
xmlSecMSCryptoKeyDataGost2001GetType(xmlSecKeyDataPtr data)2420 xmlSecMSCryptoKeyDataGost2001GetType(xmlSecKeyDataPtr data) {
2421     return(xmlSecMSCryptoKeyDataGetType(data));
2422 }
2423 
2424 static xmlSecSize
xmlSecMSCryptoKeyDataGost2001GetSize(xmlSecKeyDataPtr data)2425 xmlSecMSCryptoKeyDataGost2001GetSize(xmlSecKeyDataPtr data) {
2426     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id), 0);
2427 
2428     return xmlSecMSCryptoKeyDataGetSize(data);
2429 }
2430 
2431 static void
xmlSecMSCryptoKeyDataGost2001DebugDump(xmlSecKeyDataPtr data,FILE * output)2432 xmlSecMSCryptoKeyDataGost2001DebugDump(xmlSecKeyDataPtr data, FILE* output) {
2433     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id));
2434     xmlSecAssert(output != NULL);
2435 
2436     fprintf(output, "=== dsa key: size = %d\n",
2437             xmlSecMSCryptoKeyDataGost2001GetSize(data));
2438 }
2439 
2440 static void
xmlSecMSCryptoKeyDataGost2001DebugXmlDump(xmlSecKeyDataPtr data,FILE * output)2441 xmlSecMSCryptoKeyDataGost2001DebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
2442     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2001Id));
2443     xmlSecAssert(output != NULL);
2444 
2445     fprintf(output, "<GOST2001KeyValue size=\"%d\" />\n",
2446             xmlSecMSCryptoKeyDataGost2001GetSize(data));
2447 }
2448 
2449 #endif /* XMLSEC_NO_GOST */
2450 
2451 
2452 #ifndef XMLSEC_NO_GOST2012
2453 
2454 /**************************************************************************
2455  *
2456  * GOST2012 256 xml key representation processing.
2457  *
2458  *************************************************************************/
2459 static int              xmlSecMSCryptoKeyDataGost2012_256Initialize(xmlSecKeyDataPtr data);
2460 static int              xmlSecMSCryptoKeyDataGost2012_256Duplicate(xmlSecKeyDataPtr dst,
2461                                                          xmlSecKeyDataPtr src);
2462 static void             xmlSecMSCryptoKeyDataGost2012_256Finalize(xmlSecKeyDataPtr data);
2463 static int              xmlSecMSCryptoKeyDataGost2012_256XmlRead    (xmlSecKeyDataId id,
2464                                                          xmlSecKeyPtr key,
2465                                                          xmlNodePtr node,
2466                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
2467 static int              xmlSecMSCryptoKeyDataGost2012_256XmlWrite(xmlSecKeyDataId id,
2468                                                          xmlSecKeyPtr key,
2469                                                          xmlNodePtr node,
2470                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
2471 static int              xmlSecMSCryptoKeyDataGost2012_256Generate(xmlSecKeyDataPtr data,
2472                                                          xmlSecSize sizeBits,
2473                                                          xmlSecKeyDataType type);
2474 
2475 static xmlSecKeyDataType xmlSecMSCryptoKeyDataGost2012_256GetType(xmlSecKeyDataPtr data);
2476 static xmlSecSize        xmlSecMSCryptoKeyDataGost2012_256GetSize(xmlSecKeyDataPtr data);
2477 static void              xmlSecMSCryptoKeyDataGost2012_256DebugDump(xmlSecKeyDataPtr data,
2478                                                          FILE* output);
2479 static void             xmlSecMSCryptoKeyDataGost2012_256DebugXmlDump(xmlSecKeyDataPtr data,
2480                                                          FILE* output);
2481 
2482 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataGost2012_256Klass = {
2483     sizeof(xmlSecKeyDataKlass),
2484     xmlSecMSCryptoKeyDataSize,
2485 
2486     /* data */
2487     xmlSecNameGostR3410_2012_256KeyValue,
2488     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
2489                                         /* xmlSecKeyDataUsage usage; */
2490     xmlSecHrefGostR3410_2012_256KeyValue,         /* const xmlChar* href; */
2491     xmlSecNodeGostR3410_2012_256KeyValue,         /* const xmlChar* dataNodeName; */
2492     xmlSecDSigNs,                       /* const xmlChar* dataNodeNs; */
2493 
2494     /* constructors/destructor */
2495     xmlSecMSCryptoKeyDataGost2012_256Initialize,    /* xmlSecKeyDataInitializeMethod initialize; */
2496     xmlSecMSCryptoKeyDataGost2012_256Duplicate,     /* xmlSecKeyDataDuplicateMethod duplicate; */
2497     xmlSecMSCryptoKeyDataGost2012_256Finalize,      /* xmlSecKeyDataFinalizeMethod finalize; */
2498     NULL, /* xmlSecMSCryptoKeyDataGost2001Generate,*/   /* xmlSecKeyDataGenerateMethod generate; */
2499 
2500     /* get info */
2501     xmlSecMSCryptoKeyDataGost2012_256GetType,       /* xmlSecKeyDataGetTypeMethod getType; */
2502     xmlSecMSCryptoKeyDataGost2012_256GetSize,       /* xmlSecKeyDataGetSizeMethod getSize; */
2503     NULL,                               /* xmlSecKeyDataGetIdentifier getIdentifier; */
2504 
2505     /* read/write */
2506     NULL,       /* xmlSecKeyDataXmlReadMethod xmlRead; */
2507     NULL,       /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
2508     NULL,                               /* xmlSecKeyDataBinReadMethod binRead; */
2509     NULL,                               /* xmlSecKeyDataBinWriteMethod binWrite; */
2510 
2511     /* debug */
2512     xmlSecMSCryptoKeyDataGost2012_256DebugDump,     /* xmlSecKeyDataDebugDumpMethod debugDump; */
2513     xmlSecMSCryptoKeyDataGost2012_256DebugXmlDump,/* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
2514 
2515     /* reserved for the future */
2516     NULL,                               /* void* reserved0; */
2517     NULL,                               /* void* reserved1; */
2518 };
2519 
2520 /* Ordered list of providers to search for algorithm implementation using
2521  * xmlSecMSCryptoFindProvider() function
2522  *
2523  * MUST END with { NULL, 0 } !!!
2524  */
2525 static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Gost2012_256[] = {
2526     { CRYPTOPRO_CSP_256,            PROV_GOST_2012_256 },
2527     { NULL, 0 }
2528 };
2529 
2530 /**
2531  * xmlSecMSCryptoKeyDataGost2001GetKlass:
2532  *
2533  * The GOST2012_256 key data klass.
2534  *
2535  * Returns: pointer to GOST2012_256 key data klass.
2536  */
2537 xmlSecKeyDataId
xmlSecMSCryptoKeyDataGost2012_256GetKlass(void)2538 xmlSecMSCryptoKeyDataGost2012_256GetKlass(void) {
2539     return(&xmlSecMSCryptoKeyDataGost2012_256Klass);
2540 }
2541 
2542 
2543 static int
xmlSecMSCryptoKeyDataGost2012_256Initialize(xmlSecKeyDataPtr data)2544 xmlSecMSCryptoKeyDataGost2012_256Initialize(xmlSecKeyDataPtr data) {
2545     xmlSecMSCryptoKeyDataCtxPtr ctx;
2546     int ret;
2547 
2548     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_256Id), xmlSecKeyDataTypeUnknown);
2549 
2550     ret = xmlSecMSCryptoKeyDataInitialize(data);
2551     if(ret != 0) {
2552         xmlSecInternalError("xmlSecMSCryptoKeyDataInitialize", NULL);
2553         return(-1);
2554     }
2555 
2556     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
2557     xmlSecAssert2(ctx != NULL, -1);
2558 
2559     ctx->providers = xmlSecMSCryptoProviderInfo_Gost2012_256;
2560     return(0);
2561 }
2562 
2563 static int
xmlSecMSCryptoKeyDataGost2012_256Duplicate(xmlSecKeyDataPtr dst,xmlSecKeyDataPtr src)2564 xmlSecMSCryptoKeyDataGost2012_256Duplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
2565     xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecMSCryptoKeyDataGost2012_256Id), -1);
2566     xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecMSCryptoKeyDataGost2012_256Id), -1);
2567 
2568     return(xmlSecMSCryptoKeyDataDuplicate(dst, src));
2569 }
2570 
2571 static void
xmlSecMSCryptoKeyDataGost2012_256Finalize(xmlSecKeyDataPtr data)2572 xmlSecMSCryptoKeyDataGost2012_256Finalize(xmlSecKeyDataPtr data) {
2573     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_256Id));
2574 
2575     xmlSecMSCryptoKeyDataFinalize(data);
2576 }
2577 
2578 static xmlSecKeyDataType
xmlSecMSCryptoKeyDataGost2012_256GetType(xmlSecKeyDataPtr data)2579 xmlSecMSCryptoKeyDataGost2012_256GetType(xmlSecKeyDataPtr data) {
2580     return(xmlSecMSCryptoKeyDataGetType(data));
2581 }
2582 
2583 static xmlSecSize
xmlSecMSCryptoKeyDataGost2012_256GetSize(xmlSecKeyDataPtr data)2584 xmlSecMSCryptoKeyDataGost2012_256GetSize(xmlSecKeyDataPtr data) {
2585     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_256Id), 0);
2586 
2587     return xmlSecMSCryptoKeyDataGetSize(data);
2588 }
2589 
2590 static void
xmlSecMSCryptoKeyDataGost2012_256DebugDump(xmlSecKeyDataPtr data,FILE * output)2591 xmlSecMSCryptoKeyDataGost2012_256DebugDump(xmlSecKeyDataPtr data, FILE* output) {
2592     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_256Id));
2593     xmlSecAssert(output != NULL);
2594 
2595     fprintf(output, "=== dsa key: size = %d\n",
2596             xmlSecMSCryptoKeyDataGost2012_256GetSize(data));
2597 }
2598 
2599 static void
xmlSecMSCryptoKeyDataGost2012_256DebugXmlDump(xmlSecKeyDataPtr data,FILE * output)2600 xmlSecMSCryptoKeyDataGost2012_256DebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
2601     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_256Id));
2602     xmlSecAssert(output != NULL);
2603 
2604     fprintf(output, "<GOST2012_256KeyValue size=\"%d\" />\n",
2605             xmlSecMSCryptoKeyDataGost2012_256GetSize(data));
2606 }
2607 
2608 
2609 /**************************************************************************
2610  *
2611  * GOST2012 512 xml key representation processing.
2612  *
2613  *************************************************************************/
2614 static int              xmlSecMSCryptoKeyDataGost2012_512Initialize(xmlSecKeyDataPtr data);
2615 static int              xmlSecMSCryptoKeyDataGost2012_512Duplicate(xmlSecKeyDataPtr dst,
2616                                                          xmlSecKeyDataPtr src);
2617 static void             xmlSecMSCryptoKeyDataGost2012_512Finalize(xmlSecKeyDataPtr data);
2618 static int              xmlSecMSCryptoKeyDataGost2012_512XmlRead    (xmlSecKeyDataId id,
2619                                                          xmlSecKeyPtr key,
2620                                                          xmlNodePtr node,
2621                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
2622 static int              xmlSecMSCryptoKeyDataGost2012_512XmlWrite(xmlSecKeyDataId id,
2623                                                          xmlSecKeyPtr key,
2624                                                          xmlNodePtr node,
2625                                                          xmlSecKeyInfoCtxPtr keyInfoCtx);
2626 static int              xmlSecMSCryptoKeyDataGost2012_512Generate(xmlSecKeyDataPtr data,
2627                                                          xmlSecSize sizeBits,
2628                                                          xmlSecKeyDataType type);
2629 
2630 static xmlSecKeyDataType xmlSecMSCryptoKeyDataGost2012_512GetType(xmlSecKeyDataPtr data);
2631 static xmlSecSize        xmlSecMSCryptoKeyDataGost2012_512GetSize(xmlSecKeyDataPtr data);
2632 static void              xmlSecMSCryptoKeyDataGost2012_512DebugDump(xmlSecKeyDataPtr data,
2633                                                          FILE* output);
2634 static void             xmlSecMSCryptoKeyDataGost2012_512DebugXmlDump(xmlSecKeyDataPtr data,
2635                                                          FILE* output);
2636 
2637 static xmlSecKeyDataKlass xmlSecMSCryptoKeyDataGost2012_512Klass = {
2638     sizeof(xmlSecKeyDataKlass),
2639     xmlSecMSCryptoKeyDataSize,
2640 
2641     /* data */
2642     xmlSecNameGostR3410_2012_512KeyValue,
2643     xmlSecKeyDataUsageKeyValueNode | xmlSecKeyDataUsageRetrievalMethodNodeXml,
2644                                         /* xmlSecKeyDataUsage usage; */
2645     xmlSecHrefGostR3410_2012_512KeyValue,         /* const xmlChar* href; */
2646     xmlSecNodeGostR3410_2012_512KeyValue,         /* const xmlChar* dataNodeName; */
2647     xmlSecDSigNs,                       /* const xmlChar* dataNodeNs; */
2648 
2649     /* constructors/destructor */
2650     xmlSecMSCryptoKeyDataGost2012_512Initialize,    /* xmlSecKeyDataInitializeMethod initialize; */
2651     xmlSecMSCryptoKeyDataGost2012_512Duplicate,     /* xmlSecKeyDataDuplicateMethod duplicate; */
2652     xmlSecMSCryptoKeyDataGost2012_512Finalize,      /* xmlSecKeyDataFinalizeMethod finalize; */
2653     NULL, /* xmlSecMSCryptoKeyDataGost2001Generate,*/   /* xmlSecKeyDataGenerateMethod generate; */
2654 
2655     /* get info */
2656     xmlSecMSCryptoKeyDataGost2012_512GetType,       /* xmlSecKeyDataGetTypeMethod getType; */
2657     xmlSecMSCryptoKeyDataGost2012_512GetSize,       /* xmlSecKeyDataGetSizeMethod getSize; */
2658     NULL,                               /* xmlSecKeyDataGetIdentifier getIdentifier; */
2659 
2660     /* read/write */
2661     NULL,       /* xmlSecKeyDataXmlReadMethod xmlRead; */
2662     NULL,       /* xmlSecKeyDataXmlWriteMethod xmlWrite; */
2663     NULL,                               /* xmlSecKeyDataBinReadMethod binRead; */
2664     NULL,                               /* xmlSecKeyDataBinWriteMethod binWrite; */
2665 
2666     /* debug */
2667     xmlSecMSCryptoKeyDataGost2012_512DebugDump,     /* xmlSecKeyDataDebugDumpMethod debugDump; */
2668     xmlSecMSCryptoKeyDataGost2012_512DebugXmlDump,/* xmlSecKeyDataDebugDumpMethod debugXmlDump; */
2669 
2670     /* reserved for the future */
2671     NULL,                               /* void* reserved0; */
2672     NULL,                               /* void* reserved1; */
2673 };
2674 
2675 /* Ordered list of providers to search for algorithm implementation using
2676  * xmlSecMSCryptoFindProvider() function
2677  *
2678  * MUST END with { NULL, 0 } !!!
2679  */
2680 static xmlSecMSCryptoProviderInfo xmlSecMSCryptoProviderInfo_Gost2012_512[] = {
2681     { CRYPTOPRO_CSP_512,            PROV_GOST_2012_512 },
2682     { NULL, 0 }
2683 };
2684 
2685 /**
2686  * xmlSecMSCryptoKeyDataGost2001GetKlass:
2687  *
2688  * The GOST2012_512 key data klass.
2689  *
2690  * Returns: pointer to GOST2012_512 key data klass.
2691  */
2692 xmlSecKeyDataId
xmlSecMSCryptoKeyDataGost2012_512GetKlass(void)2693 xmlSecMSCryptoKeyDataGost2012_512GetKlass(void) {
2694     return(&xmlSecMSCryptoKeyDataGost2012_512Klass);
2695 }
2696 
2697 
2698 static int
xmlSecMSCryptoKeyDataGost2012_512Initialize(xmlSecKeyDataPtr data)2699 xmlSecMSCryptoKeyDataGost2012_512Initialize(xmlSecKeyDataPtr data) {
2700     xmlSecMSCryptoKeyDataCtxPtr ctx;
2701     int ret;
2702 
2703     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_512Id), xmlSecKeyDataTypeUnknown);
2704 
2705     ret = xmlSecMSCryptoKeyDataInitialize(data);
2706     if(ret != 0) {
2707         xmlSecInternalError("xmlSecMSCryptoKeyDataInitialize", NULL);
2708         return(-1);
2709     }
2710 
2711     ctx = xmlSecMSCryptoKeyDataGetCtx(data);
2712     xmlSecAssert2(ctx != NULL, -1);
2713 
2714     ctx->providers = xmlSecMSCryptoProviderInfo_Gost2012_512;
2715     return(0);
2716 }
2717 
2718 static int
xmlSecMSCryptoKeyDataGost2012_512Duplicate(xmlSecKeyDataPtr dst,xmlSecKeyDataPtr src)2719 xmlSecMSCryptoKeyDataGost2012_512Duplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
2720     xmlSecAssert2(xmlSecKeyDataCheckId(dst, xmlSecMSCryptoKeyDataGost2012_512Id), -1);
2721     xmlSecAssert2(xmlSecKeyDataCheckId(src, xmlSecMSCryptoKeyDataGost2012_512Id), -1);
2722 
2723     return(xmlSecMSCryptoKeyDataDuplicate(dst, src));
2724 }
2725 
2726 static void
xmlSecMSCryptoKeyDataGost2012_512Finalize(xmlSecKeyDataPtr data)2727 xmlSecMSCryptoKeyDataGost2012_512Finalize(xmlSecKeyDataPtr data) {
2728     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_512Id));
2729 
2730     xmlSecMSCryptoKeyDataFinalize(data);
2731 }
2732 
2733 static xmlSecKeyDataType
xmlSecMSCryptoKeyDataGost2012_512GetType(xmlSecKeyDataPtr data)2734 xmlSecMSCryptoKeyDataGost2012_512GetType(xmlSecKeyDataPtr data) {
2735     return(xmlSecMSCryptoKeyDataGetType(data));
2736 }
2737 
2738 static xmlSecSize
xmlSecMSCryptoKeyDataGost2012_512GetSize(xmlSecKeyDataPtr data)2739 xmlSecMSCryptoKeyDataGost2012_512GetSize(xmlSecKeyDataPtr data) {
2740     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_512Id), 0);
2741 
2742     return xmlSecMSCryptoKeyDataGetSize(data);
2743 }
2744 
2745 static void
xmlSecMSCryptoKeyDataGost2012_512DebugDump(xmlSecKeyDataPtr data,FILE * output)2746 xmlSecMSCryptoKeyDataGost2012_512DebugDump(xmlSecKeyDataPtr data, FILE* output) {
2747     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_512Id));
2748     xmlSecAssert(output != NULL);
2749 
2750     fprintf(output, "=== dsa key: size = %d\n",
2751             xmlSecMSCryptoKeyDataGost2012_512GetSize(data));
2752 }
2753 
2754 static void
xmlSecMSCryptoKeyDataGost2012_512DebugXmlDump(xmlSecKeyDataPtr data,FILE * output)2755 xmlSecMSCryptoKeyDataGost2012_512DebugXmlDump(xmlSecKeyDataPtr data, FILE* output) {
2756     xmlSecAssert(xmlSecKeyDataCheckId(data, xmlSecMSCryptoKeyDataGost2012_512Id));
2757     xmlSecAssert(output != NULL);
2758 
2759     fprintf(output, "<GOST2012_512KeyValue size=\"%d\" />\n",
2760             xmlSecMSCryptoKeyDataGost2012_512GetSize(data));
2761 }
2762 
2763 #endif /* XMLSEC_NO_GOST2012 */
2764