1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 /*
21 * XSEC
22 *
23 * NSSCryptoKeyRSA := RSA Keys
24 *
25 * Author(s): Milan Tomic
26 *
27 */
28
29 #include <xsec/enc/NSS/NSSCryptoKeyRSA.hpp>
30 #include <xsec/enc/NSS/NSSCryptoProvider.hpp>
31 #include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
32 #include <xsec/enc/XSECCryptoException.hpp>
33 #include <xsec/framework/XSECError.hpp>
34
35 #include <xercesc/util/Janitor.hpp>
36
37 #if defined (XSEC_HAVE_NSS)
38
39 #include <secder.h>
40 #include <secdig.h>
41
42 XSEC_USING_XERCES(ArrayJanitor);
43
44 // --------------------------------------------------------------------------------
45 // Constructor
46 // --------------------------------------------------------------------------------
47
NSSCryptoKeyRSA(SECKEYPublicKey * pubkey,SECKEYPrivateKey * privkey)48 NSSCryptoKeyRSA::NSSCryptoKeyRSA(SECKEYPublicKey * pubkey, SECKEYPrivateKey * privkey) {
49
50 // NOTE - We OWN those handles
51 mp_pubkey = pubkey;
52 mp_privkey = privkey;
53
54 mp_modulus = NULL;
55 mp_exponent = NULL;
56 };
57
58 // --------------------------------------------------------------------------------
59 // Destructor
60 // --------------------------------------------------------------------------------
61
~NSSCryptoKeyRSA()62 NSSCryptoKeyRSA::~NSSCryptoKeyRSA() {
63
64 // Clean up
65
66 if (mp_pubkey != 0)
67 SECKEY_DestroyPublicKey(mp_pubkey);
68
69 if (mp_privkey != 0)
70 SECKEY_DestroyPrivateKey(mp_privkey);
71
72 if (mp_modulus != NULL)
73 SECITEM_FreeItem(mp_modulus, PR_TRUE);
74
75 if (mp_exponent != NULL)
76 SECITEM_FreeItem(mp_exponent, PR_TRUE);
77 };
78
getProviderName() const79 const XMLCh * NSSCryptoKeyRSA::getProviderName() const {
80 return DSIGConstants::s_unicodeStrPROVNSS;
81 }
82
83 // --------------------------------------------------------------------------------
84 // Get key type
85 // --------------------------------------------------------------------------------
86
getKeyType() const87 XSECCryptoKey::KeyType NSSCryptoKeyRSA::getKeyType() const {
88
89 // Find out what we have
90 if (mp_pubkey == 0) {
91
92 if (mp_privkey != 0)
93 return KEY_RSA_PRIVATE;
94
95 if (mp_exponent == NULL || mp_modulus == NULL)
96 return KEY_NONE;
97 else
98 return KEY_RSA_PUBLIC;
99
100 }
101
102 if (mp_privkey != 0)
103 return KEY_RSA_PAIR;
104
105 return KEY_RSA_PUBLIC;
106 }
107
108
109 // --------------------------------------------------------------------------------
110 // Load modulus
111 // --------------------------------------------------------------------------------
112
loadPublicModulusBase64BigNums(const char * b64,unsigned int len)113 void NSSCryptoKeyRSA::loadPublicModulusBase64BigNums(const char* b64, unsigned int len) {
114
115 if (mp_modulus != NULL) {
116
117 SECITEM_FreeItem(mp_modulus, PR_TRUE);
118 mp_modulus = NULL; // In case we get an exception
119
120 }
121
122 mp_modulus = NSSCryptoProvider::b642SI(b64, len);
123
124 }
125
126 // --------------------------------------------------------------------------------
127 // Load exponent
128 // --------------------------------------------------------------------------------
129
loadPublicExponentBase64BigNums(const char * b64,unsigned int len)130 void NSSCryptoKeyRSA::loadPublicExponentBase64BigNums(const char* b64, unsigned int len) {
131
132 if (mp_exponent != NULL) {
133
134 SECITEM_FreeItem(mp_exponent, PR_TRUE);
135 mp_exponent = NULL; // In case we get an exception
136
137 }
138
139 mp_exponent = NSSCryptoProvider::b642SI(b64, len);
140
141 }
142
143 // --------------------------------------------------------------------------------
144 // Import key
145 // --------------------------------------------------------------------------------
146
importKey() const147 void NSSCryptoKeyRSA::importKey() const {
148
149 if (mp_pubkey != 0 || mp_exponent == NULL || mp_modulus == NULL)
150 return;
151
152
153 PRArenaPool * arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
154
155 if(arena == NULL) {
156
157 throw XSECCryptoException(XSECCryptoException::GeneralError,
158 "NSS:RSA Error attempting create new arena");
159
160 }
161
162 mp_pubkey = (SECKEYPublicKey*)PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
163
164 if(mp_pubkey == NULL ) {
165
166 PORT_FreeArena(arena, PR_FALSE);
167
168 throw XSECCryptoException(XSECCryptoException::GeneralError,
169 "NSS:RSA Error attempting create new arena");
170
171 }
172
173 mp_pubkey->arena = arena;
174 mp_pubkey->keyType = rsaKey;
175
176 SECStatus s = SECITEM_CopyItem(arena, &(mp_pubkey->u.rsa.modulus), mp_modulus);
177
178 if (s != SECSuccess) {
179
180 PORT_FreeArena(arena, PR_FALSE);
181
182 throw XSECCryptoException(XSECCryptoException::DSAError,
183 "NSS:RSA Error attempting to import modulus");
184
185 }
186
187 s = SECITEM_CopyItem(arena, &(mp_pubkey->u.rsa.publicExponent), mp_exponent);
188
189 if (s != SECSuccess) {
190
191 PORT_FreeArena(arena, PR_FALSE);
192
193 throw XSECCryptoException(XSECCryptoException::DSAError,
194 "NSS:RSA Error attempting to import exponent");
195
196 }
197
198 }
199
200 // --------------------------------------------------------------------------------
201 // Verify a signature encoded as a Base64 string
202 // --------------------------------------------------------------------------------
203
verifySHA1PKCS1Base64Signature(const unsigned char * hashBuf,unsigned int hashLen,const char * base64Signature,unsigned int sigLen,XSECCryptoHash::HashType type) const204 bool NSSCryptoKeyRSA::verifySHA1PKCS1Base64Signature(const unsigned char * hashBuf,
205 unsigned int hashLen,
206 const char * base64Signature,
207 unsigned int sigLen,
208 XSECCryptoHash::HashType type) const {
209
210 // Use the currently loaded key to validate the Base64 encoded signature
211
212 if (mp_pubkey == 0) {
213
214 // Try to import from the parameters
215 importKey();
216
217 if (mp_pubkey == 0) {
218 throw XSECCryptoException(XSECCryptoException::RSAError,
219 "NSS:RSA - Attempt to validate signature with empty key");
220 }
221 }
222
223 // Decode the signature
224 unsigned char * rawSig;
225 unsigned int rawSigLen;
226 XSECnew(rawSig, unsigned char[sigLen]);
227 ArrayJanitor<unsigned char> j_rawSig(rawSig);
228
229 // Decode the signature
230 XSCryptCryptoBase64 b64;
231
232 b64.decodeInit();
233 rawSigLen = b64.decode((unsigned char *) base64Signature, sigLen, rawSig, sigLen);
234 rawSigLen += b64.decodeFinish(&rawSig[rawSigLen], sigLen - rawSigLen);
235
236 SECItem signature;
237 signature.type = siBuffer;
238 signature.data = rawSig;
239 signature.len = rawSigLen;
240
241 SECItem data;
242 data.data = 0;
243 data.len = 0;
244 SECOidTag hashalg;
245 PRArenaPool * arena = 0;
246 SGNDigestInfo *di = 0;
247 SECItem * res;
248
249 switch (type) {
250
251 case (XSECCryptoHash::HASH_MD5):
252 hashalg = SEC_OID_MD5;
253 break;
254 case (XSECCryptoHash::HASH_SHA1):
255 hashalg = SEC_OID_SHA1;
256 break;
257 case (XSECCryptoHash::HASH_SHA256):
258 hashalg = SEC_OID_SHA256;
259 break;
260 case (XSECCryptoHash::HASH_SHA384):
261 hashalg = SEC_OID_SHA384;
262 break;
263 case (XSECCryptoHash::HASH_SHA512):
264 hashalg = SEC_OID_SHA512;
265 break;
266 default:
267 throw XSECCryptoException(XSECCryptoException::RSAError,
268 "NSS:RSA - Unsupported hash algorithm in RSA sign");
269 }
270
271 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
272 if (!arena) {
273 throw XSECCryptoException(XSECCryptoException::RSAError,
274 "NSS:RSA - Error creating arena");
275 }
276
277 di = SGN_CreateDigestInfo(hashalg, (unsigned char * )hashBuf, hashLen);
278 if (di == NULL) {
279
280 PORT_FreeArena(arena, PR_FALSE);
281
282 throw XSECCryptoException(XSECCryptoException::RSAError,
283 "NSS:RSA - Error creating digest info");
284 }
285
286 res = SEC_ASN1EncodeItem(arena, &data, di, NSS_Get_sgn_DigestInfoTemplate(NULL, 0));
287
288 if (!res) {
289 SGN_DestroyDigestInfo(di);
290 PORT_FreeArena(arena, PR_FALSE);
291
292 throw XSECCryptoException(XSECCryptoException::RSAError,
293 "NSS:RSA - Error encoding digest info for RSA sign");
294 }
295
296 // Verify signature
297 SECStatus s = PK11_Verify(mp_pubkey, &signature, &data, NULL);
298
299 return s == SECSuccess;
300 }
301
302 // --------------------------------------------------------------------------------
303 // Sign and encode result as a Base64 string
304 // --------------------------------------------------------------------------------
305
signSHA1PKCS1Base64Signature(unsigned char * hashBuf,unsigned int hashLen,char * base64SignatureBuf,unsigned int base64SignatureBufLen,XSECCryptoHash::HashType type) const306 unsigned int NSSCryptoKeyRSA::signSHA1PKCS1Base64Signature(unsigned char * hashBuf,
307 unsigned int hashLen,
308 char * base64SignatureBuf,
309 unsigned int base64SignatureBufLen,
310 XSECCryptoHash::HashType type) const {
311
312 // Sign a pre-calculated hash using this key
313 if (mp_privkey == 0) {
314 throw XSECCryptoException(XSECCryptoException::RSAError,
315 "NSS:RSA - Attempt to sign data using a public or un-loaded key");
316 }
317
318 unsigned char * rawSig;
319 XSECnew(rawSig, unsigned char[base64SignatureBufLen]);
320 ArrayJanitor<unsigned char> j_rawSig(rawSig);
321
322 SECItem signature;
323 signature.type = siBuffer;
324 signature.data = rawSig;
325 signature.len = base64SignatureBufLen;
326
327 SECItem data;
328 data.data = 0;
329 SECOidTag hashalg;
330 PRArenaPool * arena = 0;
331 SGNDigestInfo *di = 0;
332 SECItem * res;
333
334 switch (type) {
335
336 case (XSECCryptoHash::HASH_MD5):
337 hashalg = SEC_OID_MD5;
338 break;
339 case (XSECCryptoHash::HASH_SHA1):
340 hashalg = SEC_OID_SHA1;
341 break;
342 case (XSECCryptoHash::HASH_SHA256):
343 hashalg = SEC_OID_SHA256;
344 break;
345 case (XSECCryptoHash::HASH_SHA384):
346 hashalg = SEC_OID_SHA384;
347 break;
348 case (XSECCryptoHash::HASH_SHA512):
349 hashalg = SEC_OID_SHA512;
350 break;
351 default:
352 throw XSECCryptoException(XSECCryptoException::RSAError,
353 "NSS:RSA - Unsupported hash algorithm in RSA sign");
354 }
355
356 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
357 if (!arena) {
358 throw XSECCryptoException(XSECCryptoException::RSAError,
359 "NSS:RSA - Error creating arena");
360 }
361
362 di = SGN_CreateDigestInfo(hashalg, hashBuf, hashLen);
363 if (di == NULL) {
364 PORT_FreeArena(arena, PR_FALSE);
365
366 throw XSECCryptoException(XSECCryptoException::RSAError,
367 "NSS:RSA - Error creating digest info");
368 }
369
370 res = SEC_ASN1EncodeItem(arena, &data, di, NSS_Get_sgn_DigestInfoTemplate(NULL, 0));
371
372 if (!res) {
373 SGN_DestroyDigestInfo(di);
374 PORT_FreeArena(arena, PR_FALSE);
375
376 throw XSECCryptoException(XSECCryptoException::RSAError,
377 "NSS:RSA - Error encoding digest info for RSA sign");
378 }
379
380 /* data.type = siBuffer;
381 data.data = hashBuf;
382 data.len = hashLen;*/
383
384 /* As of V1.3.1 - create a DigestInfo block */
385
386
387 SECStatus s = PK11_Sign(mp_privkey, &signature, &data);
388
389 SGN_DestroyDigestInfo(di);
390 PORT_FreeArena(arena, PR_FALSE);
391
392 if (s != SECSuccess) {
393 throw XSECCryptoException(XSECCryptoException::RSAError,
394 "NSS:RSA - Error during signing operation");
395 }
396
397 // Now encode
398 XSCryptCryptoBase64 b64;
399 b64.encodeInit();
400 unsigned int ret = b64.encode(signature.data, signature.len, (unsigned char *) base64SignatureBuf, base64SignatureBufLen);
401 ret += b64.encodeFinish((unsigned char *) &base64SignatureBuf[ret], base64SignatureBufLen - ret);
402
403 return ret;
404 }
405
406 // --------------------------------------------------------------------------------
407 // Clone key
408 // --------------------------------------------------------------------------------
409
clone() const410 XSECCryptoKey * NSSCryptoKeyRSA::clone() const {
411
412 NSSCryptoKeyRSA * ret;
413
414 XSECnew(ret, NSSCryptoKeyRSA(mp_pubkey, mp_privkey));
415
416 if (mp_pubkey != 0) {
417 ret->mp_pubkey = SECKEY_CopyPublicKey(mp_pubkey);
418 if (ret->mp_pubkey == 0) {
419 throw XSECCryptoException(XSECCryptoException::MemoryError,
420 "NSS:RSA Error attempting to clone (copy) public key");
421 }
422 }
423
424 if (mp_privkey != 0) {
425 ret->mp_privkey = SECKEY_CopyPrivateKey(mp_privkey);
426 if (ret->mp_privkey == 0) {
427 throw XSECCryptoException(XSECCryptoException::MemoryError,
428 "NSS:RSA Error attempting to clone (copy) private key");
429 }
430 }
431
432 // Clone modulus
433 if (mp_modulus != 0) {
434 ret->mp_modulus = SECITEM_DupItem(mp_modulus);
435 if (ret->mp_modulus == 0) {
436 throw XSECCryptoException(XSECCryptoException::MemoryError,
437 "NSS:RSA Error attempting to clone (copy) modulus");
438 }
439 }
440
441 // Clone exponent
442 if (mp_exponent != 0) {
443 ret->mp_exponent = SECITEM_DupItem(mp_exponent);
444 if (ret->mp_exponent == 0) {
445 throw XSECCryptoException(XSECCryptoException::MemoryError,
446 "NSS:RSA Error attempting to clone (copy) exponent");
447 }
448 }
449
450 return ret;
451 }
452
453 // --------------------------------------------------------------------------------
454 // decrypt a buffer
455 // --------------------------------------------------------------------------------
456
privateDecrypt(const unsigned char * inBuf,unsigned char * plainBuf,unsigned int inLength,unsigned int maxOutLength,PaddingType padding,const XMLCh * hashURI,const XMLCh * mgfURI,unsigned char * params,unsigned int paramslen) const457 unsigned int NSSCryptoKeyRSA::privateDecrypt(const unsigned char * inBuf,
458 unsigned char * plainBuf,
459 unsigned int inLength,
460 unsigned int maxOutLength,
461 PaddingType padding,
462 const XMLCh* hashURI,
463 const XMLCh* mgfURI,
464 unsigned char* params,
465 unsigned int paramslen) const {
466
467 // Perform a decrypt
468 if (mp_privkey == 0) {
469 throw XSECCryptoException(XSECCryptoException::RSAError,
470 "NSS:RSA - Attempt to decrypt data with empty key");
471 }
472
473 unsigned int decryptSize = inLength;
474
475 SECStatus s;
476 unsigned char *ptr = NULL;
477
478 switch (padding) {
479
480 case XSECCryptoKeyRSA::PAD_PKCS_1_5 :
481
482 s = PK11_PubDecryptRaw(mp_privkey,
483 plainBuf,
484 (unsigned int*)&decryptSize,
485 maxOutLength,
486 (unsigned char*)inBuf,
487 inLength);
488
489 if (s != SECSuccess) {
490
491 throw XSECCryptoException(XSECCryptoException::RSAError,
492 "NSS:RSA privateKeyDecrypt - Error Decrypting PKCS1_5 padded RSA encrypt");
493
494 }
495
496 //do the padding (http://www.w3.org/TR/xmlenc-core/#rsa-1_5)
497 ptr = (unsigned char*) memchr(plainBuf, 0x02, decryptSize);
498 if( ptr )
499 {
500 unsigned int bytesToRemove = ((ptr-plainBuf)+1);
501 memmove(plainBuf, ptr+1, decryptSize-bytesToRemove);
502 decryptSize -= bytesToRemove;
503 }
504
505 ptr = (unsigned char*) memchr(plainBuf, 0x00, decryptSize);
506 if( ptr )
507 {
508 unsigned int bytesToRemove = ((ptr-plainBuf)+1);
509 memmove(plainBuf, ptr+1, decryptSize-bytesToRemove);
510 decryptSize -= bytesToRemove;
511 }
512
513 break;
514
515 case XSECCryptoKeyRSA::PAD_OAEP :
516 throw XSECCryptoException(XSECCryptoException::RSAError,
517 "NSS:RSA - OAEP padding method not supported in NSS yet");
518 break;
519
520
521 default :
522 throw XSECCryptoException(XSECCryptoException::RSAError,
523 "NSS:RSA - Unknown padding method");
524 }
525
526 return decryptSize;
527 }
528
529 // --------------------------------------------------------------------------------
530 // Encrypt a buffer
531 // --------------------------------------------------------------------------------
532
publicEncrypt(const unsigned char * inBuf,unsigned char * cipherBuf,unsigned int inLength,unsigned int maxOutLength,PaddingType padding,const XMLCh * hashURI,const XMLCh * mgfURI,unsigned char * params,unsigned int paramslen) const533 unsigned int NSSCryptoKeyRSA::publicEncrypt(const unsigned char * inBuf,
534 unsigned char * cipherBuf,
535 unsigned int inLength,
536 unsigned int maxOutLength,
537 PaddingType padding,
538 const XMLCh* hashURI,
539 const XMLCh* mgfURI,
540 unsigned char* params,
541 unsigned int paramslen) const {
542
543 // Perform an encrypt
544 if (mp_pubkey == 0) {
545 throw XSECCryptoException(XSECCryptoException::RSAError,
546 "NSS:RSA - Attempt to encrypt data with empty key");
547 }
548
549 unsigned int encryptSize = SECKEY_PublicKeyStrength(mp_pubkey);
550
551 if (maxOutLength < encryptSize) {
552 throw XSECCryptoException(XSECCryptoException::RSAError,
553 "NSS:RSA - Too small buffer for encrypted buffer output");
554 }
555
556 SECStatus s;
557
558 unsigned char * buf;
559 XSECnew(buf, unsigned char[encryptSize]);
560 ArrayJanitor<unsigned char> j_buf(buf);
561
562 switch (padding) {
563 case XSECCryptoKeyRSA::PAD_PKCS_1_5 :
564
565 // do the padding (http://www.w3.org/TR/xmlenc-core/#rsa-1_5)
566 {
567
568 // generate random data for padding
569 SECStatus s = PK11_GenerateRandom(buf, encryptSize);
570
571 if (s != SECSuccess) {
572 throw XSECException(XSECException::InternalError,
573 "NSSCryptoKeyRSA() - Error generating Random data");
574 }
575
576 // first byte have to be 0x02
577 buf[0] = 0x00;
578 buf[1] = 0x02;
579
580 // check that there are no 0x00 bytes among random data
581 for (unsigned int i = 2; i < encryptSize - inLength - 1; i++) {
582
583 while (buf[i] == 0x00) {
584 // replace all 0x00 occurences in random data with random value
585 PK11_GenerateRandom(&buf[i], 1);
586 }
587 }
588
589 // before key add 0x00 byte
590 buf[encryptSize - inLength - 1] = 0x00;
591
592 // at the end of input buffer (to be encrypted) add key
593 memcpy(&buf[encryptSize - inLength], inBuf, inLength);
594 }
595
596 // encrypt
597 s = PK11_PubEncryptRaw(mp_pubkey, cipherBuf, (unsigned char*)buf, encryptSize, NULL);
598
599 if (s != SECSuccess) {
600 throw XSECCryptoException(XSECCryptoException::RSAError,
601 "NSS:RSA publicKeyEncrypt - Error performing encrypt");
602 }
603
604 break;
605
606 case XSECCryptoKeyRSA::PAD_OAEP :
607 throw XSECCryptoException(XSECCryptoException::RSAError,
608 "NSS:RSA - OAEP padding method not supported in NSS yet");
609 break;
610
611 default :
612 throw XSECCryptoException(XSECCryptoException::RSAError,
613 "NSS:RSA - Unknown padding method");
614 }
615
616 return encryptSize;
617 }
618
619 // --------------------------------------------------------------------------------
620 // Get key size in bytes
621 // --------------------------------------------------------------------------------
622
getLength(void) const623 unsigned int NSSCryptoKeyRSA::getLength(void) const {
624
625 unsigned int ret = 0;
626
627 if (mp_pubkey != 0) {
628 ret = SECKEY_PublicKeyStrength(mp_pubkey);
629 } else if (mp_privkey != 0) {
630 ret = PK11_GetPrivateModulusLen(mp_privkey);
631 }
632
633 return ret;
634 }
635
636 // --------------------------------------------------------------------------------
637 // Load parameters from key (utility function)
638 // --------------------------------------------------------------------------------
639
loadParamsFromKey(void)640 void NSSCryptoKeyRSA::loadParamsFromKey(void) {
641
642 if (mp_pubkey == 0)
643 return;
644
645 mp_modulus = SECITEM_DupItem(&(mp_pubkey->u.rsa.modulus));
646
647 if (mp_modulus == 0) {
648 throw XSECCryptoException(XSECCryptoException::RSAError,
649 "NSS:RSA - Error during extracting modulus from public key");
650 }
651
652 mp_exponent = SECITEM_DupItem(&(mp_pubkey->u.rsa.publicExponent));
653
654 if (mp_exponent == 0) {
655 throw XSECCryptoException(XSECCryptoException::RSAError,
656 "NSS:RSA - Error during extracting exponent from public key");
657 }
658 }
659
660 // --------------------------------------------------------------------------------
661 // Get exponent
662 // --------------------------------------------------------------------------------
663
getExponentBase64BigNums(char * b64,unsigned int len)664 unsigned int NSSCryptoKeyRSA::getExponentBase64BigNums(char * b64, unsigned int len) {
665
666 if (mp_pubkey == 0 && mp_exponent == 0) {
667 return 0; // Nothing we can do
668 }
669
670 if (mp_exponent == NULL) {
671 loadParamsFromKey();
672 }
673
674 unsigned int bLen = 0;
675 unsigned char * b = NSSCryptoProvider::SI2b64(mp_exponent, bLen);
676 if (bLen > len)
677 bLen = len;
678 memcpy(b64, b, bLen);
679 delete[] b;
680
681 return bLen;
682 }
683
684 // --------------------------------------------------------------------------------
685 // Get modulus
686 // --------------------------------------------------------------------------------
687
getModulusBase64BigNums(char * b64,unsigned int len)688 unsigned int NSSCryptoKeyRSA::getModulusBase64BigNums(char * b64, unsigned int len) {
689
690 if (mp_pubkey == 0 && mp_modulus == 0) {
691 return 0; // Nothing we can do
692 }
693
694 if (mp_modulus == NULL) {
695 loadParamsFromKey();
696 }
697
698 unsigned int bLen = 0;
699 unsigned char * b = NSSCryptoProvider::SI2b64(mp_modulus, bLen);
700 if (bLen > len)
701 bLen = len;
702 memcpy(b64, b, bLen);
703 delete[] b;
704
705 return bLen;
706 }
707
708 #endif /* XSEC_HAVE_NSS */
709