1 7 8 9 package org.enhydra.oyster.activation; 10 11 import org.enhydra.oyster.cms.*; 12 import org.enhydra.oyster.util.MimeAssist; 13 import org.enhydra.oyster.util.PFXUtils; 14 import org.enhydra.oyster.util.MimeAssist; 15 import org.enhydra.oyster.exception.SMIMEException; 16 import org.enhydra.oyster.exception.SMIMEIOException; 17 import javax.mail.internet.MimeMessage ; 18 import javax.activation.DataSource ; 19 import java.io.*; 20 import java.util.Vector ; 21 import java.security.PrivateKey ; 22 import java.security.KeyStore ; 23 import java.security.cert.X509Certificate ; 24 25 32 public class CMSSignedDataSource implements DataSource { 33 34 37 private byte[] message; 38 39 42 private SignerInfos sInfo; 43 44 47 private Certificates certif; 48 49 52 private int countCert = 0; 53 54 57 private String [] capabilities; 58 59 62 private boolean externalSignature = true; 63 64 68 private boolean[] typeOfDigest = { false, false, false }; 69 70 74 private boolean[] enableOfCapabil = { false, false, false, false }; 75 76 79 private String boundary = null; 80 81 95 public CMSSignedDataSource (byte[] message0, boolean externalSignature0) throws SMIMEException 96 { 97 message = message0; 98 externalSignature = externalSignature0; 100 if(externalSignature) 101 boundary = "smime_bondary_" + Long.toString(System.currentTimeMillis()); 102 sInfo = new SignerInfos(); 103 certif = new Certificates(); 104 capabilities = new String [18]; 105 } 106 107 108 120 public CMSSignedDataSource (MimeMessage message0, boolean externalSignature0) throws SMIMEException 121 { 122 this( MimeAssist.messageConvertor(message0), externalSignature0 ); 123 } 124 125 167 public void setCapabilities (String type0, int par10, int par20, int par30, int par40, int par50) throws SMIMEException { 168 if (par10 > 5 | par10 < 0 | par20 > 5 | par20 < 0 | par30 > 5 | par30 < 0 | par40 > 5 | par40 < 0 | par50 > 5 | par50 < 0) 169 throw new SMIMEException(this, 1028); 170 if (type0.equalsIgnoreCase("SYMMETRIC")) { 171 if (enableOfCapabil[0] == true | enableOfCapabil[3] == true) 172 throw new SMIMEException(this, 1029); 173 capabilities[par10] = "RC2_CBC_40"; capabilities[par20] = "RC2_CBC_64"; capabilities[par30] = "RC2_CBC_128"; capabilities[par40] = "DES"; capabilities[par50] = "DES_EDE3_CBC"; capabilities[0] = null; enableOfCapabil[0] = true; 180 } 181 else if (type0.equalsIgnoreCase("SIGNATURE")) { 182 if (enableOfCapabil[1] == true | enableOfCapabil[3] == true) 183 throw new SMIMEException(this, 1029); 184 capabilities[par10 + 6] = "MD2_WITH_RSA"; capabilities[par20 + 6] = "MD5_WITH_RSA"; capabilities[par30 + 6] = "SHA1_WITH_RSA"; capabilities[par40 + 6] = "SHA1_WITH_DSA"; capabilities[par50 + 6] = null; capabilities[6] = null; enableOfCapabil[1] = true; 191 } 192 else if (type0.equalsIgnoreCase("ENCIPHER")) { 193 if (enableOfCapabil[2] == true | enableOfCapabil[3] == true) 194 throw new SMIMEException(this, 1029); 195 capabilities[par10 + 12] = "RSA"; capabilities[par20 + 12] = null; capabilities[par30 + 12] = null; capabilities[par40 + 12] = null; capabilities[par50 + 12] = null; capabilities[12] = null; enableOfCapabil[2] = true; 202 } 203 else if (type0.equals("DEFAULT")) { 204 for (int i = 0; i != capabilities.length; i++) 205 capabilities[i] = null; 206 capabilities[13] = "RSA"; capabilities[9] = "SHA1_WITH_RSA"; capabilities[1] = "RC2_CBC_40"; enableOfCapabil[3] = true; 210 } 211 else 212 throw new SMIMEException(this, 1030); 213 } 214 215 229 public void addSigner (KeyStore pfx0, boolean includingCert0, boolean includingSignAttrib0, String signingAlg0) throws SMIMEException { 230 231 X509Certificate [] chain = PFXUtils.getCertificateChain(pfx0); 232 if(chain == null) 233 chain = PFXUtils.getAllX509Certificate(pfx0); 234 235 PrivateKey pKey = PFXUtils.getPrivateKey(pfx0); 236 237 this.addSigner(chain, pKey, includingCert0, includingSignAttrib0, signingAlg0); 238 } 239 240 255 public void addSigner (X509Certificate [] chain0, PrivateKey privKey0, boolean includingCert0, boolean includingSignAttrib0, String signingAlg0) throws SMIMEException { 256 String digestAlg = null; 257 if (signingAlg0.equalsIgnoreCase("SHA1_WITH_RSA")) { 258 typeOfDigest[0] = true; 259 digestAlg = "SHA1"; 260 } 261 else if (signingAlg0.equalsIgnoreCase("SHA1_WITH_DSA")) { 262 typeOfDigest[0] = true; 263 digestAlg = "SHA1"; 264 } 265 else if (signingAlg0.equalsIgnoreCase("MD2_WITH_RSA")) { 266 typeOfDigest[1] = true; 267 digestAlg = "MD2"; 268 } 269 else if (signingAlg0.equalsIgnoreCase("MD5_WITH_RSA")) { 270 typeOfDigest[2] = true; 271 digestAlg = "MD5"; 272 } 273 else 274 throw new SMIMEException(this, 1031); 275 SignedAttributes attrib = null; if (includingSignAttrib0 == true) { 278 attrib = new SignedAttributes(); ContentTypeAttribute cont = new ContentTypeAttribute("ID_DATA", "NAME_STRING"); 280 attrib.addSignedAttribute(cont.getDEREncoded()); 281 SigningTimeAttribute time = new SigningTimeAttribute(); 282 attrib.addSignedAttribute(time.getDEREncoded()); 283 boolean include = false; for (int i = capabilities.length; i != 0; i--) { 285 if (capabilities[i - 1] != null) { 286 include = true; 287 break; 288 } 289 } 290 if (include == true) { 291 CapabilitiesAttribute cap = new CapabilitiesAttribute(capabilities); 292 attrib.addSignedAttribute(cap.getDEREncoded()); 293 for (int i = capabilities.length; i != 0; i--) capabilities[i - 1] = null; 295 } 296 MessageDigestAttribute dig = new MessageDigestAttribute(message, digestAlg); 297 attrib.addSignedAttribute(dig.getDEREncoded()); 298 } 299 sInfo.addSigner(message, chain0[0], privKey0, attrib, signingAlg0); if (includingCert0 == true) { 301 for (int i = 0; i != chain0.length; i++) { 303 certif.addCertificate(chain0[i]); 304 countCert++; 305 } 306 } 307 for (int i = 0; i != enableOfCapabil.length; i++) enableOfCapabil[i] = false; 309 } 310 311 317 public void addCertificate (X509Certificate cert0) throws SMIMEException { 318 certif.addCertificate(cert0); 319 countCert++; 320 } 321 322 329 public byte[] getCMSSignedObject() throws SMIMEException { 330 SignedData signData = new SignedData(); signData.addCMSVersion(new CMSVersion(1).getDEREncoded()); 332 DigestAlgorithmIdentifiers digAlg = new DigestAlgorithmIdentifiers(); 333 if (typeOfDigest[0] == true) 334 digAlg.addDigestAlgIdNullPar("SHA1", "NAME_STRING"); 335 if (typeOfDigest[1] == true) 336 digAlg.addDigestAlgIdNullPar("MD2", "NAME_STRING"); 337 if (typeOfDigest[2] == true) 338 digAlg.addDigestAlgIdNullPar("MD5", "NAME_STRING"); 339 signData.addDigestAlgorithm(digAlg.getDEREncoded()); 340 EncapsulatedContentInfo enc = new EncapsulatedContentInfo(); 341 ContentTypeIdentifier cont = new ContentTypeIdentifier("ID_DATA", "NAME_STRING"); 342 enc.addContentType(cont.getDEREncoded()); 343 if (externalSignature == false) { 344 enc.addEncapsulatedContent(message); 345 } 346 signData.addEncapsulatedContentInfo(enc.getDEREncoded()); 347 if (countCert != 0) 348 signData.addCertificate(certif.getDEREncoded()); 349 signData.addSignerInfos(sInfo.getDEREncoded()); 350 Content signedContent = new Content(signData.getDEREncoded(), true); ContentInfo cmsObjectSignedData = new ContentInfo(); 352 ContentTypeIdentifier contentTypeSignDataId = new ContentTypeIdentifier("ID_SIGNEDDATA", "NAME_STRING"); cmsObjectSignedData.addContentType(contentTypeSignDataId.getDEREncoded()); 354 cmsObjectSignedData.addContent(signedContent.getDEREncoded()); 355 return cmsObjectSignedData.getDEREncoded(); 356 } 357 358 368 public byte[] getBASE64CMSSignedObject() throws SMIMEException { 369 return MimeAssist.getBASE64WithBreakOn76(this.getCMSSignedObject()); 370 } 371 372 373 377 private String getMicalg() { 378 int sum = 0; 379 if(typeOfDigest[0]) 380 sum = sum +1; 381 if(typeOfDigest[1]) 382 sum = sum +10; 383 if(typeOfDigest[2]) 384 sum = sum +100; 385 386 switch (sum) { 387 case 0: 388 return "\"unknown\""; 389 case 1: 390 return "\"sha1\""; 391 case 10: 392 return "\"md2\""; 393 case 100: 394 return "\"md5\""; 395 case 11: 396 return "\"sha1,md2\""; 397 case 101: 398 return "\"sha1,md5\""; 399 case 110: 400 return "\"md2,md5\""; 401 case 111: 402 return "\"sha1,md2,md5\""; 403 } 404 return "\"unknown\""; 405 } 406 407 408 417 private byte[] getExternalSignedMessage() throws SMIMEException { 418 419 try { 420 String extMessage = 421 "--" + boundary + "\r\n" + 422 new String (this.message,"ISO-8859-1") + "\r\n" + 423 "--" + boundary + "\r\n" + 424 "Content-Type: application/x-pkcs7-signature; name=smime.p7s" + "\r\n" + 425 "Content-Transfer-Encoding: base64" + "\r\n" + 426 "Content-Disposition: attachment; filename=smime.p7s" + "\r\n" + "\r\n" + 427 new String (this.getBASE64CMSSignedObject(),"ISO-8859-1") + "\r\n" + 428 "--" + boundary + "--"; 429 430 return extMessage.getBytes("ISO-8859-1"); 431 } 432 catch(Exception e) { 433 throw SMIMEException.getInstance(this, e, "getExternalSignedMessage"); 434 } 435 } 436 437 438 442 public String getContentType() { 443 if (!externalSignature) 444 return "application/x-pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\""; 446 else 447 return "multipart/signed;" + "\r\n" + 449 " protocol=\"application/x-pkcs7-signature\";" + "\r\n" + 450 " micalg=" + this.getMicalg() + "; boundary=" + boundary; 451 452 } 453 454 459 public InputStream getInputStream() throws SMIMEIOException { 460 try { 461 if (!externalSignature) 462 return new ByteArrayInputStream(getCMSSignedObject()); 463 else 464 return new ByteArrayInputStream(getExternalSignedMessage()); 465 } catch (SMIMEException e) { 466 throw new SMIMEIOException(e); 467 } 468 } 469 470 474 public String getName () { 475 return "SignedDataContentInfo"; 476 } 477 478 484 public OutputStream getOutputStream () throws IOException { 485 throw new IOException("SignedDataContentInfo does not support getOutputStream()"); 486 } 487 } 488 489 490 491 | Popular Tags |