1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.xml.security.keyinfo;
18
19 import java.math.BigInteger;
20 import java.security.KeyException;
21 import java.security.KeyFactory;
22 import java.security.NoSuchAlgorithmException;
23 import java.security.PublicKey;
24 import java.security.cert.CRLException;
25 import java.security.cert.CertificateEncodingException;
26 import java.security.cert.CertificateException;
27 import java.security.cert.CertificateFactory;
28 import java.security.cert.X509CRL;
29 import java.security.cert.X509Certificate;
30 import java.security.interfaces.DSAParams;
31 import java.security.interfaces.DSAPublicKey;
32 import java.security.interfaces.RSAPublicKey;
33 import java.security.spec.DSAParameterSpec;
34 import java.security.spec.DSAPublicKeySpec;
35 import java.security.spec.InvalidKeySpecException;
36 import java.security.spec.KeySpec;
37 import java.security.spec.RSAPublicKeySpec;
38 import java.util.Collection;
39 import java.util.LinkedList;
40 import java.util.List;
41
42 import org.opensaml.xml.Configuration;
43 import org.opensaml.xml.XMLObjectBuilderFactory;
44 import org.opensaml.xml.security.x509.X509Util;
45 import org.opensaml.xml.signature.DSAKeyValue;
46 import org.opensaml.xml.signature.Exponent;
47 import org.opensaml.xml.signature.G;
48 import org.opensaml.xml.signature.KeyInfo;
49 import org.opensaml.xml.signature.KeyName;
50 import org.opensaml.xml.signature.KeyValue;
51 import org.opensaml.xml.signature.Modulus;
52 import org.opensaml.xml.signature.P;
53 import org.opensaml.xml.signature.Q;
54 import org.opensaml.xml.signature.RSAKeyValue;
55 import org.opensaml.xml.signature.X509Data;
56 import org.opensaml.xml.signature.X509IssuerName;
57 import org.opensaml.xml.signature.X509IssuerSerial;
58 import org.opensaml.xml.signature.X509SKI;
59 import org.opensaml.xml.signature.X509SerialNumber;
60 import org.opensaml.xml.signature.X509SubjectName;
61 import org.opensaml.xml.signature.Y;
62 import org.opensaml.xml.util.Base64;
63 import org.opensaml.xml.util.DatatypeHelper;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67
68
69
70
71
72
73 public class KeyInfoHelper {
74
75
76 private static Logger log = LoggerFactory.getLogger(KeyInfoHelper.class);
77
78
79
80 private static CertificateFactory x509CertFactory;
81
82
83 protected KeyInfoHelper(){
84
85 }
86
87
88
89
90
91
92
93
94 public static List<String> getKeyNames(KeyInfo keyInfo) {
95 List<String> keynameList = new LinkedList<String>();
96
97 if (keyInfo == null) {
98 return keynameList;
99 }
100
101 List<KeyName> keyNames = keyInfo.getKeyNames();
102 for (KeyName keyName : keyNames) {
103 if (keyName.getValue() != null) {
104 keynameList.add(keyName.getValue());
105 }
106 }
107
108 return keynameList;
109 }
110
111
112
113
114
115
116
117 public static void addKeyName(KeyInfo keyInfo, String keyNameValue) {
118 KeyName keyName = (KeyName) Configuration.getBuilderFactory()
119 .getBuilder(KeyName.DEFAULT_ELEMENT_NAME)
120 .buildObject(KeyName.DEFAULT_ELEMENT_NAME);
121 keyName.setValue(keyNameValue);
122 keyInfo.getKeyNames().add(keyName);
123 }
124
125
126
127
128
129
130
131
132
133
134
135 public static List<X509Certificate> getCertificates(KeyInfo keyInfo) throws CertificateException {
136 List<X509Certificate> certList = new LinkedList<X509Certificate>();
137
138 if (keyInfo == null) {
139 return certList;
140 }
141
142 List<X509Data> x509Datas = keyInfo.getX509Datas();
143 for (X509Data x509Data : x509Datas) {
144 if (x509Data != null) {
145 certList.addAll(getCertificates(x509Data));
146 }
147 }
148
149 return certList;
150 }
151
152
153
154
155
156
157
158
159
160
161
162 public static List<X509Certificate> getCertificates(X509Data x509Data) throws CertificateException {
163 List<X509Certificate> certList = new LinkedList<X509Certificate>();
164
165 if (x509Data == null) {
166 return certList;
167 }
168
169 for (org.opensaml.xml.signature.X509Certificate xmlCert : x509Data.getX509Certificates()) {
170 if (xmlCert != null && xmlCert.getValue() != null) {
171 X509Certificate newCert = getCertificate(xmlCert);
172 certList.add(newCert);
173 }
174 }
175
176 return certList;
177 }
178
179
180
181
182
183
184
185
186
187
188
189 public static X509Certificate getCertificate(org.opensaml.xml.signature.X509Certificate xmlCert)
190 throws CertificateException {
191
192 if (xmlCert == null || xmlCert.getValue() == null) {
193 return null;
194 }
195
196 Collection<X509Certificate> certs = X509Util.decodeCertificate(Base64.decode(xmlCert.getValue()));
197 if (certs != null && certs.iterator().hasNext()) {
198 return certs.iterator().next();
199 } else {
200 return null;
201 }
202 }
203
204
205
206
207
208
209
210
211
212
213
214 public static List<X509CRL> getCRLs(KeyInfo keyInfo) throws CRLException {
215 List<X509CRL> crlList = new LinkedList<X509CRL>();
216
217 if (keyInfo == null) {
218 return crlList;
219 }
220
221 List<X509Data> x509Datas = keyInfo.getX509Datas();
222 for (X509Data x509Data : x509Datas) {
223 if (x509Data != null) {
224 crlList.addAll(getCRLs(x509Data));
225 }
226 }
227
228 return crlList;
229 }
230
231
232
233
234
235
236
237
238
239
240
241 public static List<X509CRL> getCRLs(X509Data x509Data) throws CRLException {
242 List<X509CRL> crlList = new LinkedList<X509CRL>();
243
244 if (x509Data == null) {
245 return crlList;
246 }
247
248 for (org.opensaml.xml.signature.X509CRL xmlCRL : x509Data.getX509CRLs()) {
249 if (xmlCRL != null && xmlCRL.getValue() != null) {
250 X509CRL newCRL = getCRL(xmlCRL);
251 crlList.add(newCRL);
252 }
253 }
254
255 return crlList;
256 }
257
258
259
260
261
262
263
264
265
266
267
268 public static X509CRL getCRL(org.opensaml.xml.signature.X509CRL xmlCRL) throws CRLException {
269
270 if (xmlCRL == null || xmlCRL.getValue() == null) {
271 return null;
272 }
273
274 Collection<X509CRL> crls = X509Util.decodeCRLs(Base64.decode(xmlCRL.getValue()));
275 return crls.iterator().next();
276 }
277
278
279
280
281
282
283
284
285
286
287
288 public static void addCertificate(KeyInfo keyInfo, X509Certificate cert) throws CertificateEncodingException {
289 X509Data x509Data;
290 if (keyInfo.getX509Datas().size() == 0) {
291 x509Data = (X509Data) Configuration.getBuilderFactory()
292 .getBuilder(X509Data.DEFAULT_ELEMENT_NAME)
293 .buildObject(X509Data.DEFAULT_ELEMENT_NAME);
294 keyInfo.getX509Datas().add(x509Data);
295 } else {
296 x509Data = keyInfo.getX509Datas().get(0);
297 }
298 x509Data.getX509Certificates().add(buildX509Certificate(cert));
299 }
300
301
302
303
304
305
306
307
308
309
310
311 public static void addCRL(KeyInfo keyInfo, X509CRL crl) throws CRLException {
312 X509Data x509Data;
313 if (keyInfo.getX509Datas().size() == 0) {
314 x509Data = (X509Data) Configuration.getBuilderFactory()
315 .getBuilder(X509Data.DEFAULT_ELEMENT_NAME)
316 .buildObject(X509Data.DEFAULT_ELEMENT_NAME);
317 keyInfo.getX509Datas().add(x509Data);
318 } else {
319 x509Data = keyInfo.getX509Datas().get(0);
320 }
321 x509Data.getX509CRLs().add(buildX509CRL(crl));
322 }
323
324
325
326
327
328
329
330
331
332
333 public static org.opensaml.xml.signature.X509Certificate
334 buildX509Certificate(X509Certificate cert) throws CertificateEncodingException {
335 org.opensaml.xml.signature.X509Certificate xmlCert =
336 (org.opensaml.xml.signature.X509Certificate) Configuration.getBuilderFactory()
337 .getBuilder(org.opensaml.xml.signature.X509Certificate.DEFAULT_ELEMENT_NAME)
338 .buildObject(org.opensaml.xml.signature.X509Certificate.DEFAULT_ELEMENT_NAME);
339
340 xmlCert.setValue(Base64.encodeBytes(cert.getEncoded()));
341
342 return xmlCert;
343 }
344
345
346
347
348
349
350
351
352
353
354 public static org.opensaml.xml.signature.X509CRL buildX509CRL(X509CRL crl) throws CRLException {
355 org.opensaml.xml.signature.X509CRL xmlCRL =
356 (org.opensaml.xml.signature.X509CRL) Configuration.getBuilderFactory()
357 .getBuilder(org.opensaml.xml.signature.X509CRL.DEFAULT_ELEMENT_NAME)
358 .buildObject(org.opensaml.xml.signature.X509CRL.DEFAULT_ELEMENT_NAME);
359
360 xmlCRL.setValue(Base64.encodeBytes(crl.getEncoded()));
361
362 return xmlCRL;
363 }
364
365
366
367
368
369
370
371 public static X509SubjectName buildX509SubjectName(String subjectName) {
372 X509SubjectName xmlSubjectName = (X509SubjectName) Configuration.getBuilderFactory()
373 .getBuilder(X509SubjectName.DEFAULT_ELEMENT_NAME)
374 .buildObject(X509SubjectName.DEFAULT_ELEMENT_NAME);
375 xmlSubjectName.setValue(subjectName);
376 return xmlSubjectName;
377 }
378
379
380
381
382
383
384
385
386 public static X509IssuerSerial buildX509IssuerSerial(String issuerName, BigInteger serialNumber) {
387 X509IssuerName xmlIssuerName = (X509IssuerName) Configuration.getBuilderFactory()
388 .getBuilder(X509IssuerName.DEFAULT_ELEMENT_NAME)
389 .buildObject(X509IssuerName.DEFAULT_ELEMENT_NAME);
390 xmlIssuerName.setValue(issuerName);
391
392 X509SerialNumber xmlSerialNumber = (X509SerialNumber) Configuration.getBuilderFactory()
393 .getBuilder(X509SerialNumber.DEFAULT_ELEMENT_NAME)
394 .buildObject(X509SerialNumber.DEFAULT_ELEMENT_NAME);
395 xmlSerialNumber.setValue(serialNumber);
396
397 X509IssuerSerial xmlIssuerSerial = (X509IssuerSerial) Configuration.getBuilderFactory()
398 .getBuilder(X509IssuerSerial.DEFAULT_ELEMENT_NAME)
399 .buildObject(X509IssuerSerial.DEFAULT_ELEMENT_NAME);
400 xmlIssuerSerial.setX509IssuerName(xmlIssuerName);
401 xmlIssuerSerial.setX509SerialNumber(xmlSerialNumber);
402
403 return xmlIssuerSerial;
404 }
405
406
407
408
409
410
411
412
413 public static X509SKI buildX509SKI(X509Certificate javaCert) {
414 byte[] skiPlainValue = X509Util.getSubjectKeyIdentifier(javaCert);
415 if (skiPlainValue == null || skiPlainValue.length == 0) {
416 return null;
417 }
418
419 X509SKI xmlSKI = (X509SKI) Configuration.getBuilderFactory()
420 .getBuilder(X509SKI.DEFAULT_ELEMENT_NAME)
421 .buildObject(X509SKI.DEFAULT_ELEMENT_NAME);
422 xmlSKI.setValue(Base64.encodeBytes(skiPlainValue));
423
424 return xmlSKI;
425 }
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440 public static void addPublicKey(KeyInfo keyInfo, PublicKey pk) throws IllegalArgumentException {
441 KeyValue keyValue = (KeyValue) Configuration.getBuilderFactory()
442 .getBuilder(KeyValue.DEFAULT_ELEMENT_NAME)
443 .buildObject(KeyValue.DEFAULT_ELEMENT_NAME);
444
445 if (pk instanceof RSAPublicKey) {
446 keyValue.setRSAKeyValue(buildRSAKeyValue((RSAPublicKey) pk));
447 } else if (pk instanceof DSAPublicKey) {
448 keyValue.setDSAKeyValue(buildDSAKeyValue((DSAPublicKey) pk));
449 } else {
450 throw new IllegalArgumentException("Only RSAPublicKey and DSAPublicKey are supported");
451 }
452
453 keyInfo.getKeyValues().add(keyValue);
454 }
455
456
457
458
459
460
461
462 public static RSAKeyValue buildRSAKeyValue(RSAPublicKey rsaPubKey) {
463 XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
464 RSAKeyValue rsaKeyValue = (RSAKeyValue) builderFactory
465 .getBuilder(RSAKeyValue.DEFAULT_ELEMENT_NAME)
466 .buildObject(RSAKeyValue.DEFAULT_ELEMENT_NAME);
467 Modulus modulus = (Modulus) builderFactory
468 .getBuilder(Modulus.DEFAULT_ELEMENT_NAME)
469 .buildObject(Modulus.DEFAULT_ELEMENT_NAME);
470 Exponent exponent = (Exponent) builderFactory
471 .getBuilder(Exponent.DEFAULT_ELEMENT_NAME)
472 .buildObject(Exponent.DEFAULT_ELEMENT_NAME);
473
474 modulus.setValueBigInt(rsaPubKey.getModulus());
475 rsaKeyValue.setModulus(modulus);
476
477 exponent.setValueBigInt(rsaPubKey.getPublicExponent());
478 rsaKeyValue.setExponent(exponent);
479
480 return rsaKeyValue;
481 }
482
483
484
485
486
487
488
489 public static DSAKeyValue buildDSAKeyValue(DSAPublicKey dsaPubKey) {
490 XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
491 DSAKeyValue dsaKeyValue = (DSAKeyValue) builderFactory
492 .getBuilder(DSAKeyValue.DEFAULT_ELEMENT_NAME)
493 .buildObject(DSAKeyValue.DEFAULT_ELEMENT_NAME);
494 Y y = (Y) builderFactory.getBuilder(Y.DEFAULT_ELEMENT_NAME).buildObject(Y.DEFAULT_ELEMENT_NAME);
495 G g = (G) builderFactory.getBuilder(G.DEFAULT_ELEMENT_NAME).buildObject(G.DEFAULT_ELEMENT_NAME);
496 P p = (P) builderFactory.getBuilder(P.DEFAULT_ELEMENT_NAME).buildObject(P.DEFAULT_ELEMENT_NAME);
497 Q q = (Q) builderFactory.getBuilder(Q.DEFAULT_ELEMENT_NAME).buildObject(Q.DEFAULT_ELEMENT_NAME);
498
499 y.setValueBigInt(dsaPubKey.getY());
500 dsaKeyValue.setY(y);
501
502 g.setValueBigInt(dsaPubKey.getParams().getG());
503 dsaKeyValue.setG(g);
504
505 p.setValueBigInt(dsaPubKey.getParams().getP());
506 dsaKeyValue.setP(p);
507
508 q.setValueBigInt(dsaPubKey.getParams().getQ());
509 dsaKeyValue.setQ(q);
510
511 return dsaKeyValue;
512 }
513
514
515
516
517
518
519
520
521
522
523
524
525 public static List<PublicKey> getPublicKeys(KeyInfo keyInfo) throws KeyException{
526 List<PublicKey> keys = new LinkedList<PublicKey>();
527
528 if (keyInfo == null || keyInfo.getKeyValues() == null) {
529 return keys;
530 }
531
532 for(KeyValue keyDescriptor : keyInfo.getKeyValues()){
533 keys.add(getKey(keyDescriptor));
534 }
535
536 return keys;
537 }
538
539
540
541
542
543
544
545
546
547
548 public static PublicKey getKey(KeyValue keyValue) throws KeyException{
549 if(keyValue.getDSAKeyValue() != null){
550 return getDSAKey(keyValue.getDSAKeyValue());
551 }else if(keyValue.getRSAKeyValue() != null){
552 return getRSAKey(keyValue.getRSAKeyValue());
553 }else{
554 return null;
555 }
556 }
557
558
559
560
561
562
563
564
565
566
567
568
569
570 public static PublicKey getDSAKey(DSAKeyValue keyDescriptor) throws KeyException {
571 if (! hasCompleteDSAParams(keyDescriptor)) {
572 throw new KeyException("DSAKeyValue element did not contain at least one of DSA parameters P, Q or G");
573 }
574
575 BigInteger gComponent = keyDescriptor.getG().getValueBigInt();
576 BigInteger pComponent = keyDescriptor.getP().getValueBigInt();
577 BigInteger qComponent = keyDescriptor.getQ().getValueBigInt();
578
579 DSAParams dsaParams = new DSAParameterSpec(pComponent, qComponent, gComponent);
580 return getDSAKey(keyDescriptor, dsaParams);
581 }
582
583
584
585
586
587
588
589
590
591
592
593
594
595 public static PublicKey getDSAKey(DSAKeyValue keyDescriptor, DSAParams dsaParams) throws KeyException {
596 BigInteger yComponent = keyDescriptor.getY().getValueBigInt();
597
598 DSAPublicKeySpec keySpec =
599 new DSAPublicKeySpec(yComponent, dsaParams.getP(), dsaParams.getQ(), dsaParams.getG());
600 return buildKey(keySpec, "DSA");
601 }
602
603
604
605
606
607
608
609
610
611 public static boolean hasCompleteDSAParams(DSAKeyValue keyDescriptor) {
612 if ( keyDescriptor.getG() == null || DatatypeHelper.isEmpty(keyDescriptor.getG().getValue())
613 || keyDescriptor.getP() == null || DatatypeHelper.isEmpty(keyDescriptor.getP().getValue())
614 || keyDescriptor.getQ() == null || DatatypeHelper.isEmpty(keyDescriptor.getQ().getValue())
615 ) {
616 return false;
617 }
618 return true;
619 }
620
621
622
623
624
625
626
627
628
629
630
631 public static PublicKey getRSAKey(RSAKeyValue keyDescriptor) throws KeyException {
632 BigInteger modulus = keyDescriptor.getModulus().getValueBigInt();
633 BigInteger exponent = keyDescriptor.getExponent().getValueBigInt();
634
635 RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
636 return buildKey(keySpec, "RSA");
637 }
638
639
640
641
642
643
644
645 public static final BigInteger decodeBigIntegerFromCryptoBinary(String base64Value) {
646 return new BigInteger(1, Base64.decode(base64Value));
647 }
648
649
650
651
652
653
654
655 public static final String encodeCryptoBinaryFromBigInteger(BigInteger bigInt) {
656
657 byte[] bigIntBytes = org.apache.xml.security.utils.Base64.encode(bigInt, bigInt.bitLength());
658 return Base64.encodeBytes(bigIntBytes);
659 }
660
661
662
663
664
665
666
667
668
669
670
671
672 protected static PublicKey buildKey(KeySpec keySpec, String keyAlgorithm) throws KeyException {
673 try {
674 KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
675 return keyFactory.generatePublic(keySpec);
676 } catch (NoSuchAlgorithmException e) {
677 log.error(keyAlgorithm + " algorithm is not supported by this VM", e);
678 throw new KeyException(keyAlgorithm + "algorithm is not supported by the JCE", e);
679 } catch (InvalidKeySpecException e) {
680 log.error("Invalid key information", e);
681 throw new KeyException("Invalid key information", e);
682 }
683 }
684
685
686
687
688
689
690
691
692 protected static CertificateFactory getX509CertFactory() throws CertificateException {
693
694 if (x509CertFactory == null) {
695 x509CertFactory = CertificateFactory.getInstance("X.509");
696 }
697
698 return x509CertFactory;
699 }
700 }