smimeutilities.java
来自「一个用java写的mail.里面的代码值得我们去研究!学习。」· Java 代码 · 共 1,087 行 · 第 1/3 页
JAVA
1,087 行
System.out.println( "Content is multipart signed: s-" + p7sPart + ", c-" + part_ ); } } else if ( msg.isMimeType( "application/pkcs7-mime" ) ) { p7sPart = findPKCS7Part( msg, "application/pkcs7-mime" ); if ( Debug_ > 0 ) { System.out.println( "Content is pkcs7-mime: " + p7sPart ); } } else if ( msg.isMimeType( "application/x-pkcs7-mime" ) ) { p7sPart = findPKCS7Part( msg, "application/x-pkcs7-mime" ); if ( Debug_ > 0 ) { System.out.println( "Content is x-pkcs7-mime: " + p7sPart ); } } if ( p7sPart != null ) { InputStream xis = null; ContentInfo xci = null; try { xis = p7sPart.getInputStream(); xci = new ContentInfo( xis ); if ( xci != null ) { result = parseContentInfo( session, xci ); if ( result != null && isSMimeMessage( result ) ) { result = getContentMessage( session, result ); } } } catch ( Exception ex ) { throw new MessagingException( ex.toString() ); } finally { if ( xis != null ) { try { xis.close(); } catch ( IOException ex ) { } } } } } catch ( Exception ex ) { throw new MessagingException( ex.toString() ); } return result; } protected Part parseContentInfo( Session session, ContentInfo info ) throws MessagingException, MissingCertificateException, PasswordCancelException { if ( Package.DEBUG && Package.isTraceable( "SMimeUtilities" ) ) { System.out.println( "SMimeUtilities.parseContentInfo(s,c)" ); } Part result = null; ObjectID objID = info.getContentType(); if ( objID.equals( ObjectID.pkcs7_signedData ) || objID.equals( ObjectID.pkcs7_data ) ) { result = parsePKCS7Content( session, info.getContent() ); } else if ( objID.equals( ObjectID.pkcs7_envelopedData ) ) { EnvelopedData eData = (EnvelopedData) info.getContent(); PKCS7Content pkcsObj = parseEnvelopedDataContent( eData ); result = parsePKCS7Content( session, pkcsObj ); } else if ( objID.equals( ObjectID.pkcs7_signedAndEnvelopedData ) ) { SignedAndEnvelopedData saeData = (SignedAndEnvelopedData) info.getContent(); PKCS7Content pkcsObj = parseSignedAndEnvelopedDataContent( saeData ); result = parsePKCS7Content( session, pkcsObj ); } return result; } protected Part parsePKCS7Content( Session session, PKCS7Content info ) throws MessagingException, MissingCertificateException, PasswordCancelException { if ( Package.DEBUG && Package.isTraceable( "SMimeUtilities" ) ) { System.out.println( "SMimeUtilities.parsePKCS7Content(s,pc)" ); } Part result = null; ObjectID objID = info.getContentType(); if ( objID.equals( ObjectID.pkcs7_signedData ) ) { signed_ = true; SignedData sData = (SignedData) info; if ( part_ != null && sData.getMode() == SignedData.EXPLICIT ) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); part_.writeTo( baos ); ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() ); sData.setInputStream( bais ); } catch ( IOException ex ) { ex.printStackTrace(); } } InputStream in = sData.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { StreamUtilities.copyStream( in, baos ); } catch ( IOException ex ) { ex.printStackTrace(); throw new MessagingException( ex.toString() ); } Data rawContent = new Data( baos.toByteArray() ); // UNDONE - should be APPENDING these certificates, NOT overwriting! certificates_ = sData.getCertificates(); signerInfos_ = sData.getSignerInfos(); // UNDONE - Verify the signatures.../* X509Certificate ax509Certificate[] = new X509Certificate[ signerInfos_.length ]; for (int i = 0; i < asignerInfo.length; i++) { if ( x509Certificate == null ) ax509Certificate[i] = signedData.getCertificate ( asignerInfo[i].getIssuerAndSerialNumber() ); else ax509Certificate[i] = x509Certificate; signedData.verify( ax509Certificate[i].getPublicKey(), i ); } if ( ej != null && !ej.validateCertificates(ax509Certificate) ) throw new PKCSException("Could not verify signing certificate");*/ result = parsePKCS7Content( session, rawContent ); } else if ( objID.equals( ObjectID.pkcs7_envelopedData ) ) { EnvelopedData eData = (EnvelopedData) info; PKCS7Content pkcsObj = parseEnvelopedDataContent( eData ); result = parsePKCS7Content( session, pkcsObj ); } else if ( objID.equals( ObjectID.pkcs7_signedAndEnvelopedData ) ) { SignedAndEnvelopedData saeData = (SignedAndEnvelopedData) info; PKCS7Content pkcsObj = parseSignedAndEnvelopedDataContent( saeData ); result = parsePKCS7Content( session, pkcsObj ); } else if ( objID.equals( ObjectID.pkcs7_data ) ) { Data data = (Data) info; MimeMessage innerMsg = new MimeMessage( session, data.getInputStream() ); innerMsg.saveChanges(); result = innerMsg; } return result; } // UNDONE // REVIEW // Currently, we are just looping through reciption infos and looking // for *any* digital ID that has a matching signing certificate issuer // and serial number. We use that id's private key. What we ought to be // doing is somehow indicating the preferred "recipient" address, and // then ? and ordering of addresses? a current default? a default based // on the folder? a default based on the To:, then CC:? // protected PKCS7Content parseEnvelopedDataContent( EnvelopedData eData ) throws MessagingException, MissingCertificateException, PasswordCancelException { if ( Package.DEBUG && Package.isTraceable( "SMimeUtilities" ) ) { System.out.println( "SMimeUtilities.parseEnvelopedDataContent(e)" ); } PKCS7Content result = null; try { PrivateKey pKey = null; SecurityConfig cfgSec = SecurityConfig.getInstance(); int recipIdx = -1; recipientInfos_ = eData.getRecipientInfos(); if ( Debug_ > 0 ) { System.out.println( "Recipients: " + recipientInfos_.length ); } for ( int ri = 0 ; ri < recipientInfos_.length ; ++ri ) { IssuerAndSerialNumber iasn = recipientInfos_[ri].getIssuerAndSerialNumber(); pKey = cfgSec.locatePrivateKey( iasn ); if ( pKey != null ) { recipIdx = ri; break; } } // REVIEW // This is probably "email not for us". We should gracefully // report that we are not able to view this email... // if ( recipIdx < 0 || recipIdx >= recipientInfos_.length ) { throw new MissingCertificateException( "could not locate a digital ID to decrypt message" ); } EncryptedContentInfo eInfo = eData.getEncryptedContentInfo(); ObjectID eObjID = eInfo.getContentType(); eData.setupCipher( pKey, recipIdx ); InputStream encIn = eData.getInputStream(); result = readPKCS7Object( eObjID, encIn ); recipientInfos_ = eData.getRecipientInfos(); algorithm_ = eInfo.getContentEncryptionAlgorithm(); if ( Debug_ > 0 ) { System.out.println( "Algorithm is " + algorithm_.getName() ); }/*System.err.println( "ENVELOPED: NUM REIPIENT INFOS = " + recipientInfos_.length );System.err.println( "ENVELOPED: ALGORITHM = " + algorithm_.getImplementationName() );System.err.println( "ENVELOPED: ALGORITHM = " + algorithm_.getAlgorithm().getName() );AlgorithmParameters params = algorithm_.getAlgorithmParameters( "PbeWithSHAAnd40BitRC2_CBC" );System.err.println( "ENVELOPED: PARAMS = " + params ); ASN1Object algAsn1 = algorithm_.getParameter();System.err.println( "ENVELOPED: ALGORITHM PARAM = " + algAsn1 );System.err.println( "ENVELOPED: ALGORITHM ASNTyPe = " + algAsn1.getAsnType() ); int compCnt = algAsn1.countComponents(); for ( int i = 0 ; i < compCnt ; ++i ) { ASN1Object comp = algAsn1.getComponentAt(i);System.err.println( "ENVELOPED: ALGORITHM PARM COMP["+i+"] = " + comp ); }*/ enveloped_ = true; } catch ( Exception ex ) { ex.printStackTrace(); throw new MessagingException( ex.toString() ); } return result; } protected PKCS7Content parseSignedAndEnvelopedDataContent( SignedAndEnvelopedData saeData ) throws MessagingException, MissingCertificateException, PasswordCancelException { if ( Package.DEBUG && Package.isTraceable( "SMimeUtilities" ) ) { System.out.println( "SMimeUtilities.parseSignedAndEnvelopedDataContent(s)" ); } PKCS7Content result = null; try { PrivateKey pKey = null; SecurityConfig cfgSec = SecurityConfig.getInstance(); // UNDONE - should be APPENDING these certificates, NOT overwriting! certificates_ = saeData.getCertificates(); signerInfos_ = saeData.getSignerInfos(); int recipIdx = -1; recipientInfos_ = saeData.getRecipientInfos(); for ( int ri = 0 ; ri < recipientInfos_.length ; ++ri ) { IssuerAndSerialNumber iasn = recipientInfos_[ri].getIssuerAndSerialNumber(); pKey = cfgSec.locatePrivateKey( iasn ); if ( pKey != null ) { recipIdx = ri; break; } } // REVIEW // This is probably "email not for us". We should gracefully // report that we are not able to view this email... // if ( recipIdx < 0 || recipIdx >= recipientInfos_.length ) { throw new MissingCertificateException( "could not locate a digital ID to decrypt message" ); } EncryptedContentInfo eInfo = saeData.getEncryptedContentInfo(); ObjectID eObjID = eInfo.getContentType(); saeData.setupCipher( pKey, recipIdx ); InputStream encIn = saeData.getInputStream(); result = readPKCS7Object( eObjID, encIn ); signed_ = true; enveloped_ = true; } catch ( Exception ex ) { throw new MessagingException( ex.toString() ); } return result; } protected PKCS7Content readPKCS7Object( ObjectID eObjID, InputStream encIn ) throws IOException, PKCSException { if ( Package.DEBUG && Package.isTraceable( "SMimeUtilities" ) ) { System.out.println( "SMimeUtilities.readPKCS7Object(o,i)" ); } PKCS7Content pkcsObj; if ( eObjID.equals( ObjectID.pkcs7_data ) ) { byte[] copyBuf = new byte[ 8 * 1024 ]; ByteArrayOutputStream dOut = new ByteArrayOutputStream(); for ( ; ; ) { int num = encIn.read( copyBuf ); if ( num == -1 ) break; if ( num > 0 ) dOut.write( copyBuf, 0, num ); } pkcsObj = new Data( dOut.toByteArray() ); } else if ( eObjID.equals( ObjectID.pkcs7_signedData ) ) { pkcsObj = new SignedData( encIn ); } else if ( eObjID.equals( ObjectID.pkcs7_envelopedData ) ) { pkcsObj = new EnvelopedData( encIn ); } else if ( eObjID.equals( ObjectID.pkcs7_signedAndEnvelopedData ) ) { pkcsObj = new SignedAndEnvelopedData( encIn ); } else if ( eObjID.equals( ObjectID.pkcs7_digestedData ) ) { pkcsObj = new DigestedData( encIn ); } else if ( eObjID.equals( ObjectID.pkcs7_encryptedData ) ) { pkcsObj = new EncryptedData( encIn ); } else { throw new PKCSException( "unknown content type '" + eObjID.getName() + "'" ); } return pkcsObj; } protected Part findPKCS7Part( Part bodyPart, String partType ) throws MessagingException, IOException { if ( Package.DEBUG && Package.isTraceable( "SMimeUtilities" ) ) { System.out.println( "SMimeUtilities.findPKCS7Part(p,t): " + partType ); } Part result = null; String partName = bodyPart.getFileName(); String contentType = bodyPart.getContentType(); if ( bodyPart.isMimeType( "multipart/*" ) ) { // ----------------------------------------------------- // ---------- M U L T I P A R T // ----------------------------------------------------- Multipart mPart = (Multipart) bodyPart.getContent(); for ( int i = 0, partCount = mPart.getCount(); i < partCount && result == null ; i++ ) { result = findPKCS7Part( mPart.getBodyPart(i), partType ); } } else if ( bodyPart.isMimeType( partType ) ) { // ----------------------------------------------------- // ---------- application/pkcs7-signature // ----------------------------------------------------- result = bodyPart; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?