1 17 package org.apache.servicemix.soap.handlers.security; 18 19 import java.io.ByteArrayInputStream ; 20 import java.io.InputStream ; 21 import java.math.BigInteger ; 22 import java.security.InvalidAlgorithmParameterException ; 23 import java.security.KeyStore ; 24 import java.security.KeyStoreException ; 25 import java.security.MessageDigest ; 26 import java.security.NoSuchAlgorithmException ; 27 import java.security.NoSuchProviderException ; 28 import java.security.PrivateKey ; 29 import java.security.PublicKey ; 30 import java.security.cert.CertPath ; 31 import java.security.cert.CertPathValidator ; 32 import java.security.cert.CertPathValidatorException ; 33 import java.security.cert.Certificate ; 34 import java.security.cert.CertificateEncodingException ; 35 import java.security.cert.CertificateException ; 36 import java.security.cert.CertificateFactory ; 37 import java.security.cert.PKIXParameters ; 38 import java.security.cert.TrustAnchor ; 39 import java.security.cert.X509Certificate ; 40 import java.security.interfaces.RSAPublicKey ; 41 import java.util.ArrayList ; 42 import java.util.Arrays ; 43 import java.util.HashSet ; 44 import java.util.Iterator ; 45 import java.util.List ; 46 import java.util.Set ; 47 import java.util.Vector ; 48 49 import org.apache.ws.security.WSSecurityException; 50 import org.apache.ws.security.components.crypto.Crypto; 51 import org.apache.ws.security.components.crypto.X509NameTokenizer; 52 53 public abstract class BaseCrypto implements Crypto { 54 55 private static final String SKI_OID = "2.5.29.14"; 56 57 private String provider; 58 private CertificateFactory certFact; 59 private String defaultX509Alias; 60 61 64 public void setDefaultX509Alias(String defaultX509Alias) { 65 this.defaultX509Alias = defaultX509Alias; 66 } 67 68 71 public String getProvider() { 72 return provider; 73 } 74 75 78 public void setProvider(String provider) { 79 this.provider = provider; 80 } 81 82 90 public String getAliasForX509Cert(Certificate cert) throws WSSecurityException { 91 try { 92 String alias = getCertificateAlias(cert); 93 if (alias != null) 94 return alias; 95 String [] allAliases = getAliases(); 97 for (int i = 0; i < allAliases.length; i++) { 98 Certificate cert2 = getCertificate(alias); 99 if (cert2.equals(cert)) { 100 return alias; 101 } 102 } 103 } catch (KeyStoreException e) { 104 throw new WSSecurityException(WSSecurityException.FAILURE, 105 "keystore"); 106 } 107 return null; 108 } 109 110 122 public String getAliasForX509Cert(String issuer) throws WSSecurityException { 123 return getAliasForX509Cert(issuer, null, false); 124 } 125 126 140 public String getAliasForX509Cert(byte[] skiBytes) throws WSSecurityException { 141 Certificate cert = null; 142 try { 143 String [] allAliases = getAliases(); 144 for (int i = 0; i < allAliases.length; i++) { 145 String alias = allAliases[i]; 146 cert = getCertificateChainOrCertificate(alias); 147 if (cert instanceof X509Certificate ) { 148 byte[] data = getSKIBytesFromCert((X509Certificate ) cert); 149 if (Arrays.equals(data, skiBytes)) { 150 return alias; 151 } 152 } 153 } 154 } catch (KeyStoreException e) { 155 throw new WSSecurityException(WSSecurityException.FAILURE, "keystore"); 156 } 157 return null; 158 } 159 160 173 public String getAliasForX509Cert(String issuer, BigInteger serialNumber) throws WSSecurityException { 174 return getAliasForX509Cert(issuer, serialNumber, true); 175 } 176 177 191 public String getAliasForX509CertThumb(byte[] thumb) throws WSSecurityException { 192 Certificate cert = null; 193 MessageDigest sha = null; 194 try { 195 sha = MessageDigest.getInstance("SHA-1"); 196 } catch (NoSuchAlgorithmException e1) { 197 throw new WSSecurityException(0, "noSHA1availabe"); 198 } 199 try { 200 String [] allAliases = getAliases(); 201 for (int i = 0; i < allAliases.length; i++) { 202 String alias = allAliases[i]; 203 cert = getCertificateChainOrCertificate(alias); 204 if (cert instanceof X509Certificate ) { 205 sha.reset(); 206 try { 207 sha.update(cert.getEncoded()); 208 } catch (CertificateEncodingException e1) { 209 throw new WSSecurityException( 210 WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, 211 "encodeError"); 212 } 213 byte[] data = sha.digest(); 214 if (Arrays.equals(data, thumb)) { 215 return alias; 216 } 217 } 218 } 219 } catch (KeyStoreException e) { 220 throw new WSSecurityException(WSSecurityException.FAILURE, 221 "keystore"); 222 } 223 return null; 224 } 225 226 237 public String [] getAliasesForDN(String subjectDN) throws WSSecurityException { 238 Vector aliases = new Vector (); 240 Certificate cert = null; 241 Vector subjectRDN = splitAndTrim(subjectDN); 243 try { 245 String [] allAliases = getAliases(); 246 for (int i = 0; i < allAliases.length; i++) { 247 String alias = allAliases[i]; 248 cert = getCertificateChainOrCertificate(alias); 249 if (cert instanceof X509Certificate ) { 250 Vector foundRDN = splitAndTrim(((X509Certificate ) cert).getSubjectDN().getName()); 251 if (subjectRDN.equals(foundRDN)) { 252 aliases.add(alias); 253 } 254 } 255 } 256 } catch (KeyStoreException e) { 257 throw new WSSecurityException(WSSecurityException.FAILURE, "keystore"); 258 } 259 return (String []) aliases.toArray(new String [aliases.size()]); 261 } 262 263 274 public byte[] getCertificateData(boolean reverse, X509Certificate [] certs) throws WSSecurityException { 275 Vector list = new Vector (); 276 for (int i = 0; i < certs.length; i++) { 277 if (reverse) { 278 list.insertElementAt(certs[i], 0); 279 } else { 280 list.add(certs[i]); 281 } 282 } 283 try { 284 CertPath path = getCertificateFactory().generateCertPath(list); 285 return path.getEncoded(); 286 } catch (CertificateEncodingException e) { 287 throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, 288 "encodeError"); 289 } catch (CertificateException e) { 290 throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, 291 "parseError"); 292 } 293 } 294 295 304 public synchronized CertificateFactory getCertificateFactory() throws WSSecurityException { 305 if (certFact == null) { 306 try { 307 if (provider == null || provider.length() == 0) { 308 certFact = CertificateFactory.getInstance("X.509"); 309 } else { 310 certFact = CertificateFactory.getInstance("X.509", provider); 311 } 312 } catch (CertificateException e) { 313 throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, 314 "unsupportedCertType"); 315 } catch (NoSuchProviderException e) { 316 throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, 317 "noSecProvider"); 318 } 319 } 320 return certFact; 321 } 322 323 331 public X509Certificate [] getCertificates(String alias) throws WSSecurityException { 332 try { 333 Certificate [] certs = getCertificateChain(alias); 334 if (certs != null && certs.length > 0) { 335 List x509certs = new ArrayList (); 336 for (int i = 0; i < certs.length; i++) { 337 if (certs[i] instanceof X509Certificate ) { 338 x509certs.add(certs[i]); 339 } 340 } 341 return (X509Certificate []) x509certs.toArray(new X509Certificate [x509certs.size()]); 342 } 343 Certificate cert = getCertificate(alias); 345 if (cert instanceof X509Certificate ) { 346 return new X509Certificate [] { (X509Certificate ) cert }; 347 } 348 return null; 349 } catch (KeyStoreException e) { 350 throw new WSSecurityException(WSSecurityException.FAILURE, "keystore"); 351 } 352 } 353 354 public String getDefaultX509Alias() { 355 return defaultX509Alias; 356 } 357 358 public KeyStore getKeyStore() { 359 return null; 360 } 361 362 371 public abstract PrivateKey getPrivateKey(String alias, String password) throws Exception ; 372 373 385 public byte[] getSKIBytesFromCert(X509Certificate cert) throws WSSecurityException { 386 391 byte[] derEncodedValue = cert.getExtensionValue(SKI_OID); 392 if (cert.getVersion() < 3 || derEncodedValue == null) { 393 PublicKey key = cert.getPublicKey(); 394 if (!(key instanceof RSAPublicKey )) { 395 throw new WSSecurityException(1, "noSKIHandling", new Object [] { "Support for RSA key only" }); 396 } 397 byte[] encoded = key.getEncoded(); 398 byte[] value = new byte[encoded.length - 22]; 400 System.arraycopy(encoded, 22, value, 0, value.length); 401 MessageDigest sha; 402 try { 403 sha = MessageDigest.getInstance("SHA-1"); 404 } catch (NoSuchAlgorithmException ex) { 405 throw new WSSecurityException(1, "noSKIHandling", new Object [] { "Wrong certificate version (<3) and no SHA1 message digest availabe" }); 406 } 407 sha.reset(); 408 sha.update(value); 409 return sha.digest(); 410 } 411 415 byte abyte0[] = new byte[derEncodedValue.length - 4]; 416 System.arraycopy(derEncodedValue, 4, abyte0, 0, abyte0.length); 417 return abyte0; 418 } 419 420 public X509Certificate [] getX509Certificates(byte[] data, boolean reverse) throws WSSecurityException { 421 InputStream in = new ByteArrayInputStream (data); 422 CertPath path = null; 423 try { 424 path = getCertificateFactory().generateCertPath(in); 425 } catch (CertificateException e) { 426 throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, 427 "parseError"); 428 } 429 List l = path.getCertificates(); 430 X509Certificate [] certs = new X509Certificate [l.size()]; 431 Iterator iterator = l.iterator(); 432 for (int i = 0; i < l.size(); i++) { 433 certs[(reverse) ? (l.size() - 1 - i) : i] = (X509Certificate ) iterator.next(); 434 } 435 return certs; 436 } 437 438 446 public X509Certificate loadCertificate(InputStream in) throws WSSecurityException { 447 X509Certificate cert = null; 448 try { 449 cert = (X509Certificate ) getCertificateFactory().generateCertificate(in); 450 } catch (CertificateException e) { 451 throw new WSSecurityException(WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, 452 "parseError"); 453 } 454 return cert; 455 } 456 457 465 public boolean validateCertPath(X509Certificate [] certs) throws WSSecurityException { 466 try { 467 java.util.List certList = java.util.Arrays.asList(certs); 469 CertPath path = this.getCertificateFactory().generateCertPath(certList); 470 471 Set hashSet = new HashSet (); 473 String [] aliases = getTrustCertificates(); 474 for (int i = 0; i < aliases.length; i++) { 475 Certificate cert = getCertificate(aliases[i]); 476 if (cert instanceof X509Certificate ) { 477 hashSet.add(new TrustAnchor ((X509Certificate ) cert, null)); 478 } 479 } 480 PKIXParameters param = new PKIXParameters (hashSet); 481 param.setRevocationEnabled(false); 483 CertPathValidator certPathValidator; 485 if (provider == null || provider.length() == 0) { 486 certPathValidator = CertPathValidator.getInstance("PKIX"); 487 } else { 488 certPathValidator = CertPathValidator.getInstance("PKIX", provider); 489 } 490 certPathValidator.validate(path, param); 491 } catch (NoSuchProviderException ex) { 492 throw new WSSecurityException(WSSecurityException.FAILURE, 493 "certpath", new Object [] { ex.getMessage() }, 494 (Throwable ) ex); 495 } catch (NoSuchAlgorithmException ex) { 496 throw new WSSecurityException(WSSecurityException.FAILURE, 497 "certpath", new Object [] { ex.getMessage() }, 498 (Throwable ) ex); 499 } catch (CertificateException ex) { 500 throw new WSSecurityException(WSSecurityException.FAILURE, 501 "certpath", new Object [] { ex.getMessage() }, 502 (Throwable ) ex); 503 } catch (InvalidAlgorithmParameterException ex) { 504 throw new WSSecurityException(WSSecurityException.FAILURE, 505 "certpath", new Object [] { ex.getMessage() }, 506 (Throwable ) ex); 507 } catch (CertPathValidatorException ex) { 508 throw new WSSecurityException(WSSecurityException.FAILURE, 509 "certpath", new Object [] { ex.getMessage() }, 510 (Throwable ) ex); 511 } catch (KeyStoreException ex) { 512 throw new WSSecurityException(WSSecurityException.FAILURE, 513 "certpath", new Object [] { ex.getMessage() }, 514 (Throwable ) ex); 515 } 516 517 return true; 518 } 519 520 protected Vector splitAndTrim(String inString) { 521 X509NameTokenizer nmTokens = new X509NameTokenizer(inString); 522 Vector vr = new Vector (); 523 524 while (nmTokens.hasMoreTokens()) { 525 vr.add(nmTokens.nextToken()); 526 } 527 java.util.Collections.sort(vr); 528 return vr; 529 } 530 531 protected Certificate getCertificateChainOrCertificate(String alias) throws KeyStoreException { 532 Certificate [] certs = getCertificateChain(alias); 533 Certificate cert = null; 534 if (certs == null || certs.length == 0) { 535 cert = getCertificate(alias); 537 if (cert == null) { 538 return null; 539 } 540 } else { 541 cert = certs[0]; 542 } 543 return cert; 544 } 545 546 554 private String getAliasForX509Cert(String issuer, BigInteger serialNumber, 555 boolean useSerialNumber) 556 throws WSSecurityException { 557 Vector issuerRDN = splitAndTrim(issuer); 558 X509Certificate x509cert = null; 559 Vector certRDN = null; 560 Certificate cert = null; 561 562 try { 563 String [] allAliases = getAliases(); 564 for (int i = 0; i < allAliases.length; i++) { 565 String alias = allAliases[i]; 566 cert = getCertificateChainOrCertificate(alias); 567 if (cert instanceof X509Certificate ) { 568 x509cert = (X509Certificate ) cert; 569 if (!useSerialNumber || 570 useSerialNumber && x509cert.getSerialNumber().compareTo(serialNumber) == 0) { 571 certRDN = splitAndTrim(x509cert.getIssuerDN().getName()); 572 if (certRDN.equals(issuerRDN)) { 573 return alias; 574 } 575 } 576 } 577 } 578 } catch (KeyStoreException e) { 579 throw new WSSecurityException(WSSecurityException.FAILURE, 580 "keystore"); 581 } 582 return null; 583 } 584 585 protected abstract String [] getAliases() throws KeyStoreException ; 586 587 protected abstract Certificate [] getCertificateChain(String alias) throws KeyStoreException ; 588 589 protected abstract Certificate getCertificate(String alias) throws KeyStoreException ; 590 591 protected abstract String getCertificateAlias(Certificate cert) throws KeyStoreException ; 592 593 protected abstract String [] getTrustCertificates() throws KeyStoreException ; 594 595 } 596 | Popular Tags |