DataPower

 View Only

Creating a S/MIME Email via XSLT

  • 1.  Creating a S/MIME Email via XSLT

    Posted 25 days ago

    Hello there,

    I have a flow that consists of picking up a file via SFTP and then creating an email with that file as an attachment. This email has to be sent encrypted and signed by SMIME.

    I've got the first part figured out. I'm able to pick up the file, create a standardised email, and add that as an attachment. 

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mime="urn:iso:identified-organization:dod:internet:mail:mixer" xmlns:func="http://exslt.org/functions" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dp="http://www.datapower.com/extensions" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="dp date func mime" version="1.0">
    	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    	
    	<!-- some constants -->
    	<xsl:variable name="CRLF" select="'&#13;&#10;'"/>
    	<xsl:variable name="TAB" select="'&#09;'"/>
    	<xsl:variable name="DDASH" select="'--'"/>
    	<xsl:variable name="QUOT" select="'&quot;'"/>
    
    	
    	<xsl:template match="/">
    	
    		<!-- Message Text -->
    		<!-- FROM -->
    		<xsl:variable name="SENDER_EAN" select="substring(substring-after(dp:variable('var://service/URI'),'/sender/'),1,13)"/>
    		<!-- TO -->
    		<xsl:variable name="RECEIVER_EAN" select="substring(substring-after(dp:variable('var://service/URI'),concat('/sender/',$SENDER_EAN,'/')),1,13)"/>
    		<!-- Filename -->
    		<xsl:variable name="FILENAME" select="substring-before(substring-after(dp:variable('var://service/URI'),concat('/sender/',$SENDER_EAN,'/')),'.edn')"/>
    		<!-- HTML email text -->
    		<xsl:variable name="html">GENERATED EMAIL TEXT.</xsl:variable>
    		<!-- prepare HTML email body for sending -->
    		<xsl:variable name="serializedHTMLData">
    			<dp:serialize select="$html" omit-xml-decl="yes"/>
    		</xsl:variable>
    		
    		<xsl:variable name="message">
    			<xsl:value-of select="dp:encode(dp:binaryNodeToString(dp:variable('var://context/INPUT')),'base-64')"/>
    		</xsl:variable>
    
    		...
    
    		<xsl:variable name="response">
    			<!-- send HTML mail-->
    			<dp:url-open target="{concat('dpsmtp://mailrelayapp.com:25/?To=xxx@x.com&amp;From=xxx@x.com&amp;Domain=x.com&amp;Subject=Test_EMAIL&amp;MIME=true')}" response="responsecode-ignore">
    				<xsl:value-of disable-output-escaping="yes" select="concat('MIME-Version: 1.0',$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat('Content-Type: multipart/mixed;',$CRLF,$TAB,'boundary=',$QUOT)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat($boundary,$QUOT,$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat($CRLF,$CRLF,$DDASH,$boundary,$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat('Content-Type: text/plain;',$CRLF,$TAB,'charset=',$QUOT,'iso-8859-1',$QUOT,$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat('Content-Transfer-Encoding: 7bit',$CRLF,$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="$serializedHTMLData"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat($CRLF,$DDASH,$boundary,$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat('Content-type: application/edine;',$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat($TAB,'name=',$QUOT,$FILENAME,'.edn',$QUOT,$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat('Content-Transfer-Encoding: base64',$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat('Content-Disposition: attachment;',$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat($TAB,'filename=',$QUOT,$FILENAME,'.edn',$QUOT,$CRLF,$CRLF)"/>
    				<xsl:value-of disable-output-escaping="yes" select="mime:split64($message)"/>
    				<xsl:value-of disable-output-escaping="yes" select="concat($CRLF,$DDASH,$boundary,$DDASH,$CRLF)"/>
    			</dp:url-open>
    		</xsl:variable>
    
    		<xsl:if test="$response/url-open/statuscode = '16' 
    		or $response/url-open/statuscode = '17' 
    		or $response/url-open/statuscode = '18'
    		or $response/url-open/errorstring = 'Cannot create connection'">
    			<dp:reject override="true">Error sending mail</dp:reject>
    		</xsl:if>
    
    	</xsl:template>
    	<!-- MIME base64 data maximal line length is 76 characters -->
    	<func:function name="mime:split64">
    		<xsl:param name="str"/>
    		<func:result>
    			<xsl:value-of select="concat(substring($str,1,76),$CRLF)"/>
    			<xsl:if test="string-length($str) > 76">
    				<xsl:value-of select="mime:split64(substring($str,77))"/>
    			</xsl:if>
    		</func:result>
    	</func:function>
    </xsl:stylesheet>

    This seems to work fine, as the mail correctly arrives with its attachment.

    However now I'm at the tricky part of implementing SMIME signing and encryption and I am unsure how to even start.I know I'll have to change the mime header to application/pkcs7-mime. But the actual encryption/signing is a bit unclear.
    My gut feeling tells me to first create a new mime-signature header and use dp:sign to generate the base64 signature, and then put all that through a dp:encrypt-string and put that in the Content-Type: application/x-pkcs7-mime header. My lack of experience in S/MIME is holding me back, since I've not been able to find an example on how exactly my key encrypted base64 data should look.

    So I thought I'd ask around here, perhaps there is someone with S/MIME experience willing to give me some pointers.

    Cheers!



    ------------------------------
    Alexander Timmermans
    ------------------------------