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 + -
显示快捷键?