=pod =head1 NAME smime - integrating S/MIME support in Mailman SSLS =head1 WARNING This document holds mainly internal stuff as well as extremely verbose debug logs. Unless you are working in close cooperation with Joost van Baal on integrating S/MIME with Mailman SSLS, it's contents is likely not interesting for you. One day, relevant stuff from this document will get moved to its proper place: the patch or external projects. =head1 INTRODUCTION If you want to be convinced I to use S/MIME, read http://www.cs.auckland.ac.nz/~pgut001/pubs/pkitutorial.pdf . gnupg-1.9.17 is development branch. Has S/MIME support. Development versions of GnuPG Note that GnuPG 1.9.x is quite different from the older versions and under heavy development. The S/MIME part (i.e. gpgsm and gpg-agent) are however pretty stable and useful. For OpenPGP use, please use gnupg 1.4.x Debian ships gnupg2 (1.9.15-6) 7 Apr 2005, which builds the gpgsm binary package. =head1 Python S/MIME interfaces alternatieve python S/MIME library: =head2 m2crypto http://sandbox.rulemaker.net/ngps/m2/ "The current version of M2Crypto is 0.13, released on 30 March 2004." geloof dat er nog wel commits plaatsvinden. heeft OpenSSL 0.9.7 nodig, dus zou kunnen conflicteren met gpl-ed code? van Ng Pheng Siong banach:/usr/local/src/python_smime_verify/ m2crypto_0.13-1.1_i386.deb People seem to use this one for S/MIME. =head2 pyOpenSSL pyOpenSSL 0.6 (in debian: python-pyopenssl) since 2001-07, latest 2004-08 http://packages.debian.org/unstable/source/pyopenssl This one seems to be the best OpenSSL interface. Needs OpenSSL 0.9.7. Upstream list is quiet but alive. =head2 amkcrypto http://www.amk.ca/python/code/crypto.html A.M. Kuchling python-crypto .deb 2004-08 =head2 python-gnutls http://home.o2w.net/~ivo/python-gnutls/dist/ / http://www.lychnis.net/index/meta/python-gnutls.lychnis zit in netbsd ports collectie 2003-12 =head2 pyGnuTLS http://freshmeat.net/projects/pygnutls/ Adam Langley http://www.imperialviolet.org/pygnutls.html no .deb, no itp nor rfp 2005-06 banach:/usr/local/src/pygnutls/ =head2 PyME http://pyme.sourceforge.net/ : python interface to GPGME library. Klinkt goed! at 2002-11 is was uploaded: #169807 python2.2-pyme_0.5.0_i386 gopher://erwin.complete.org/0/devel/pyme/SVN/debian/changelog Igor Belyi still maintains debian/ in cvs on SF. Bug #213124 From: John Goerzen To: 213124-done@bugs.debian.org Subject: Pyme removed from unstable Date: Wed, 22 Oct 2003 13:43:39 -0500 Per my request, Pyme has been removed from unstable. Therefore, open bugs referring to pyme are being closed. -- John Applied patch as listed in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=213124&archive=yes to ~/cvs/sf/pyme/pyme/debian (that hadn't been done yet.) Announced on pyme-help list. =head2 other stuff TLS Lite python module http://trevp.net/tlslite/ since 2004-01, latest 2005-02 no .deb SSLCrypto old? CryptKit http://sourceforge.net/projects/cryptkit/ 2001-11 Python OpenSSL Wrappers http://sourceforge.net/projects/pow 2002-09 PySSL http://www-2.cs.cmu.edu/~spapadim/sw/ 2000-07 : old mxCrypto Bug#100081: ITP: amkcrypto nah, use pyopenssl =head1 Status of pyme Debian package Ubuntu CVS - Arch gateway: joostvb@banach:~/arch% tla register-archive http://arch.ubuntu.com/pyme@arch.ubuntu.com Registering archive: pyme@arch.ubuntu.com joostvb@banach:~/arch% tla get pyme@arch.ubuntu.com/pyme--MAIN--0 pyme NB: works with tla-1.3.3-2, fails with tla 1.3.1 (the one in sarge) joostvb@banach:~/arch/pyme% tla changelog | grep Author all work has been done by belyi. Ubuntu development: https://wiki.ubuntu.com//DeveloperResources Tue 09 13:18 < jvb> i see ubuntu has a pyme cvs mirror on http://arch.ubuntu.com/, but it contains no ubuntu-specific patches. does this mean no ubuntu-developer is working on the pyme package? Tue 09 13:19 < bob2> jvb: no, they're stored seperately Tue 09 13:19 < jvb> bob2: aha! Tue 09 13:19 < bob2> jvb: arch.ubuntu.com (which will become bazaar.ubuntu.com) is just for cvs imports at the moment Have filed RFP Bug #322168 . =head1 GnuPG Made Easy Library joostvb@shamir:~% pinfo gpgme =head1 Needed Debian packages As of 2005-08-11, gpgsm 1.9.15-6 is latest debian package. upstream: 1.9.17 (S/MIME and gpg-agent) released 2005-06-21 "most parts (in particular GPG-AGENT and GPGSM) are considered ready for production use." (upstream 1.9.16 released 2005-04-21) Have build .deb from 1.9.17. Zie ook Bug #306890 : gnupg2: new upstream available. dpkg-deb: building package `libksba-dev' in `../libksba-dev_0.9.12-1_i386.deb'. dpkg-deb: building package `libksba8' in `../libksba8_0.9.12-1_i386.deb'. gnupg2/1.9.18/gnupg-1.9.18 =head1 importing a private key =head2 introduction gnupg manual "Using the GNU Privacy Guard" says: 3.6.4 Importing a Secret Key This operation is not yet supportted by GpgAgent. Specialized tools are to be used for this. There is no actual need because we can expect that secret keys created by a 3rd party are stored on a smartcard. If we have generated the key ourself, we do not need to import it. gnupg-1.9.19/README : private-keys-v1.d/ Directory holding the private keys maintained by gpg-agent. For detailed info see agent/keyformat.txt. Note that there is a helper tool gpg-protect-tool which may be used to protect or unprotect keys. This is however nothing a user should care about. HOW TO IMPORT A PRIVATE KEY =========================== There is some limited support to import a private key from a PKCS-12 file. gpgsm --import foo.p12 This requires that the gpg-agent is running. keyformat.txt is not shipped with tarball. Fetch from version control: banach:svn/cvs.gnupg.org/gnupg/GNUPG-1-9-BRANCH/agent/keyformat.txt Between 2005-04 and 2005-09-26, no interesting commits were done on gpgsm. We can just stay with 1.9.18, if needed. protected private keys are binary blobs in private-keys-v1.d/*.key, protected by a password. Unprotected ones are plain ascii. =head2 how NOT to do it joostvb@shamir:~/dot-gnupg-test/.smime/keys% head ddd65994.0 -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAyXnvfk8HJ8sexSQtohMAhZecyVr/xGJyJyu5CoZyFx6Be/DL GnSGNT67qUuZgwaGD7vh60uUd/ZFQT7Nux06ehwb1nvPleCX2gKt5w/lmy8ZUoyQ joostvb@shamir:~/dot-gnupg-test/.smime/keys% gpgsm --import ddd65994.0 gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: no issuer found in certificate gpgsm: basic certificate checks failed - not imported joostvb@shamir:~/dot-gnupg-test/.smime/certificates% head ddd65994.0 -----BEGIN CERTIFICATE----- MIIEPDCCAySgAwIBAgIRAIMhaGQ7RgpSizMQQU+kmDQwDQYJKoZIhvcNAQEFBQAw gYUxCzAJBgNVBAYTAk5MMSEwHwYDVQQKExhVbml2ZXJzaXRlaXQgdmFuIFRpbGJ1 joostvb@shamir:~/dot-gnupg-test/.smime/certificates% gpgsm --import ddd65994.0 gpgsm: issuer certificate {009104E0A8FF566A8F3677A1EB3ACF253CA06496} not found using authorityKeyIdentifier gpgsm: issuer certificate (#/CN=UvT-CA,1.2.840.113549.1.9.1=#5576542D4341407576742E6E6C,OU=UvT Certification Authority,O=Universiteit van Tilburg,C=NL) not found gpgsm: total number processed: 1 gpgsm: unchanged: 1 joostvb@shamir:~/dot-gnupg-test/.smime% gpgsm --import ca-bundle.crt gpgsm: total number processed: 2 gpgsm: unchanged: 2 joostvb@shamir:~/dot-gnupg-test/.smime% cp ~/gpgsm.conf ~/.gnupg joostvb@shamir:~/dot-gnupg-test/.smime% openssl pkcs12 -export -in keys/ddd65994.0 -out keys/ddd65994.p12 -name "My Certificate" No certificate matches private key joostvb@shamir:~/dot-gnupg-test/.smime% openssl pkcs12 -export -in keys/ddd65994.0 -out keys/ddd65994.p12 -name "My Certificate" -certfile certificates/ddd65994.0 joostvb@shamir:~/dot-gnupg-test/.smime% openssl pkcs12 -export -in keys/ddd65994.0 -out keys/ddd65994.p12 -name "My Certificate" -certfile certificates/ddd65994.0 No certificate matches private key joostvb@shamir:~/dot-gnupg-test/.smime% openssl pkcs12 -export -in keys/ddd65994.0 -out keys/ddd65994.p12 -name "My Certificate" -certfile ca-bundle.crt No certificate matches private key joostvb-net@banach:~% openssl pkcs12 -export -in joostvb.key -out joostvb.p12 ; echo No certificate matches private key joostvb-net@banach:~% openssl pkcs12 -export -in joostvb.key -out joostvb.p12 -name "Joost van Baal" -certfile joostvb.crt -certfile /etc/ssl/certs/surfnet-root.pem ; echo No certificate matches private key :( Perhaps GnuTLS's certtool is helpful: http://www.gnu.org/software/gnutls/manual/html_node/Invoking-certtool.html#Invoking-certtool certtool is shipped with gnutls-bin Debian package. joostvb@shamir:~% certtool --generate-privkey --outfile ca-key.pem joostvb@shamir:~% certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca-cert.pem Country name (2 chars): Organization name: Organizational unit name: Locality name: State or province name: Common name: Joost van Baal (test) UID: This field should not be used in new certificates. E-mail: Enter the certificate's serial number (decimal): Activation/Expiration time. The certificate will expire in (days): 21 Extensions. Does the certificate belong to an authority? (Y/N): N Is this a TLS web client certificate? (Y/N): N Is this also a TLS web server certificate? (Y/N): N Enter the e-mail of the subject of the certificate: joostvb@uvt.nl Will the certificate be used for signing (required for TLS)? (Y/N): Y Will the certificate be used for encryption (not required for TLS)? (Y/N): Y Enter the URI of the CRL distribution point: X.509 certificate info: Version: 3 Serial Number (hex): 00 Subject: CN=Joost van Baal (test) Validity: Not Before: Tue Oct 4 10:12:00 2005 Not After: Tue Oct 25 10:12:00 2005 Subject Public Key Info: Public Key Algorithm: RSA (1024 bits) X.509 Extensions: Subject Alternative name: RFC822name: joostvb@uvt.nl Basic Constraints: (critical) CA:FALSE Key usage: (critical) Digital signature. Key encipherment. Subject Key ID: 44 cc 64 cc 9b ee e3 03 cd 6c da 39 fb cc 22 9b 77 b8 53 f2 Other information: Public Key ID: 44 cc 64 cc 9b ee e3 03 cd 6c da 39 fb cc 22 9b 77 b8 53 f2 GNUPGHOME=/home/joostvb GPG_AGENT_INFO=/home/joostvb/S.gpg-agent:25027:1 GPG_TTY=/dev/pts/7 joostvb@shamir:~% unset GNUPGHOME GPG_AGENT_INFO GPG_TTY joostvb@shamir:~% export GPG_TTY=`tty` joostvb@shamir:~% eval `gpg-agent --daemon --use-standard-socket` joostvb@shamir:~% gpgsm --import ca-cert.pem gpgsm: self-signed certificate has a BAD signature: Bad signature gpgsm: basic certificate checks failed - not imported joostvb@shamir:~% certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca-cert.pem Generating a self signed certificate... Please enter the details of the certificate's distinguished name. Just press enter to ignore a field. Country name (2 chars): NL Organization name: UvT Organizational unit name: Locality name: State or province name: Common name: Joost van Baal (test) UID: This field should not be used in new certificates. E-mail: Enter the certificate's serial number (decimal): Activation/Expiration time. The certificate will expire in (days): 21 Extensions. Does the certificate belong to an authority? (Y/N): Y Is this a TLS web client certificate? (Y/N): N Is this also a TLS web server certificate? (Y/N): N Enter the e-mail of the subject of the certificate: joostvb@uvt.nl Will the certificate be used to sign other certificates? (Y/N): Y Will the certificate be used to sign CRLs? (Y/N): Y Will the certificate be used to sign code? (Y/N): Y Will the certificate be used to sign OCSP requests? (Y/N): Y Will the certificate be used for time stamping? (Y/N): Y Enter the URI of the CRL distribution point: X.509 certificate info: Version: 3 Serial Number (hex): 00 Subject: C=NL,O=UvT,CN=Joost van Baal (test) Validity: Not Before: Tue Oct 4 10:21:00 2005 Not After: Tue Oct 25 10:21:00 2005 Subject Public Key Info: Public Key Algorithm: RSA (1024 bits) X.509 Extensions: Subject Alternative name: RFC822name: joostvb@uvt.nl Basic Constraints: (critical) CA:TRUE Key usage: (critical) Certificate signing. CRL signing. Key purpose OIDs: Code signing. OCSP signing. Time stamping. Subject Key ID: 47 27 9c 97 74 f4 b7 43 8e eb 44 df b5 a6 d6 3c 01 dd 76 6e Other information: Public Key ID: 47 27 9c 97 74 f4 b7 43 8e eb 44 df b5 a6 d6 3c 01 dd 76 6e Is the above information ok? (Y/N): Y Signing certificate... joostvb@shamir:~% cat .gnupg/gpgsm.conf disable-crl-checks faked-system-time 1008241200 joostvb@shamir:~% vim .gnupg/gpgsm.conf joostvb@shamir:~% cat .gnupg/gpgsm.conf disable-crl-checks Nope, helpt niet: joostvb@shamir:~% gpgsm --import ca-cert.pem gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: self-signed certificate has a BAD signature: Bad signature gpgsm: basic certificate checks failed - not imported gpgsm: total number processed: 1 gpgsm: not imported: 1 joostvb@shamir:~% certtool --generate-privkey --outfile key.pem joostvb@shamir:~% certtool --generate-request --load-privkey key.pem --outfile request.pem password : "a" joostvb@shamir:~% certtool --generate-certificate --load-request request.pem --outfile cert.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem Generating a signed certificate... Loading CA's private key... Loading CA's certificate... Enter the certificate's serial number (decimal): Activation/Expiration time. The certificate will expire in (days): 21 Extensions. Does the certificate belong to an authority? (Y/N): N Is this a TLS web client certificate? (Y/N): N Is this also a TLS web server certificate? (Y/N): N Enter the e-mail of the subject of the certificate: joostvb@uvt.nl Will the certificate be used for signing (required for TLS)? (Y/N): Y Will the certificate be used for encryption (not required for TLS)? (Y/N): Y X.509 certificate info: Version: 3 Serial Number (hex): 00 Subject: C=NL,O=UvT,CN=Joost van Baal (key) Validity: Not Before: Tue Oct 4 10:31:00 2005 Not After: Tue Oct 25 10:31:00 2005 Subject Public Key Info: Public Key Algorithm: RSA (1024 bits) X.509 Extensions: Subject Alternative name: RFC822name: joostvb@uvt.nl Basic Constraints: (critical) CA:FALSE Key usage: (critical) Digital signature. Key encipherment. Subject Key ID: 89 ca 05 b2 a5 4e 4f 21 c4 c6 1f de b2 4c 0e 10 9f 4b 82 ac Authority Key ID: 47 27 9c 97 74 f4 b7 43 8e eb 44 df b5 a6 d6 3c 01 dd 76 6e Other information: Public Key ID: 89 ca 05 b2 a5 4e 4f 21 c4 c6 1f de b2 4c 0e 10 9f 4b 82 ac Is the above information ok? (Y/N): Y Signing certificate... (NB: this works: gpgsm --import < ~/.smime/ca-bundle.crt: joostvb@shamir:~% gpgsm --import < dot-gnupg-test/.smime/ca-bundle.crt gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: total number processed: 2 gpgsm: unchanged: 2 Hrm, doesn't seem to actually _do_ something... Should I hack trustkeys.txt ? joostvb@shamir:~% certtool --certificate-info --infile cert.pem "trustlist.txt" 14L, 775C written: added the "Authority Key ID:" from cert.pem to it. joostvb@shamir:~% gpgsm --import < cert.pem gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: issuer certificate {47279C9774F4B7438EEB44DFB5A6D63C01DD766E} not found using authorityKeyIdentifier gpgsm: issuer certificate (#/CN=Joost van Baal (test),O=UvT,C=NL) not found gpgsm: issuer certificate {47279C9774F4B7438EEB44DFB5A6D63C01DD766E} not found using authorityKeyIdentifier gpgsm: total number processed: 1 gpgsm: imported: 1 !?!??! Now shown with gpgsm --list-keys. However, NOT shown with --list-secret-keys ! joostvb@shamir:~% certtool --load-certificate cert.pem --load-privkey key.pem --to-p12 --outder --outfile key.p12 a joostvb@shamir:~% gpgsm --import < key.p12 asks for passphrase using curses thingie ... gpgsm: gpg-protect-tool: encryptedData error at "bag.encryptedData.keyinfo", offset 79 gpgsm: gpg-protect-tool: error at "bag.encryptedData", offset 49 gpgsm: gpg-protect-tool: error parsing or decrypting the PKCS-12 file gpgsm: error running `/usr/lib//gpg-protect-tool': exit status 2 gpgsm: total number processed: 0 Opnieuw: joostvb@shamir:~% certtool --generate-privkey --outfile ca-key.pem joostvb@shamir:~% certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca-cert.pem Country name (2 chars): NL Organization name: UvT Organizational unit name: Locality name: State or province name: Common name: Joost van Baal CA UID: joostvb This field should not be used in new certificates. E-mail: joostvb@uvt.nl Enter the certificate's serial number (decimal): 1 The certificate will expire in (days): 21 Does the certificate belong to an authority? (Y/N): Y Is this a TLS web client certificate? (Y/N): N Is this also a TLS web server certificate? (Y/N): N Enter the e-mail of the subject of the certificate: joostvb@uvt.nl Will the certificate be used to sign other certificates? (Y/N): Y Will the certificate be used to sign CRLs? (Y/N): N Will the certificate be used to sign code? (Y/N): N Will the certificate be used to sign OCSP requests? (Y/N): N Will the certificate be used for time stamping? (Y/N): N Enter the URI of the CRL distribution point: joostvb@shamir:~% certtool --generate-privkey --outfile key.pem joostvb@shamir:~% certtool --generate-request --load-privkey key.pem --outfile request.pem Generating a PKCS #10 certificate request... Country name (2 chars): NL Organization name: UvT Organizational unit name: Locality name: State or province name: Common name: Joost van Baal key a joostvb@shamir:~% certtool --generate-certificate --load-request request.pem --outfile cert.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem joostvb@shamir:~% certtool --generate-certificate --load-request request.pem --outfile cert.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem Generating a signed certificate... Loading CA's private key... Loading CA's certificate... Enter the certificate's serial number (decimal): 1 Activation/Expiration time. The certificate will expire in (days): 21 Extensions. Does the certificate belong to an authority? (Y/N): N Is this a TLS web client certificate? (Y/N): N Is this also a TLS web server certificate? (Y/N): N Enter the e-mail of the subject of the certificate: joostvb@uvt.nl Will the certificate be used for signing (required for TLS)? (Y/N): Y Will the certificate be used for encryption (not required for TLS)? (Y/N): Y joostvb@shamir:~% gpgsm --import < ca-cert.pem gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: self-signed certificate has a BAD signature: Bad signature gpgsm: basic certificate checks failed - not imported gpgsm: total number processed: 1 gpgsm: not imported: 1 Do it with openssl: self-signed certificate: first a key: openssl genrsa -des3 -out privkey.pem 2048 "aaaa" then the self-signed thing: openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095 Country Name (2 letter code) [AU]:NL State or Province Name (full name) [Some-State]:. Locality Name (eg, city) []:. Organization Name (eg, company) [Internet Widgits Pty Ltd]:UvT Organizational Unit Name (eg, section) []:. Common Name (eg, YOUR name) []:Joost van Baal CA Email Address []:joostvb@uvt.nl -rw-rw-r-- 1 joostvb joostvb 1751 Oct 4 13:38 privkey.pem -rw-rw-r-- 1 joostvb joostvb 1505 Oct 4 13:38 cacert.pem joostvb@shamir:~% gpgsm --import cacert.pem gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: total number processed: 1 gpgsm: imported: 1 joostvb@shamir:~% gpgsm --import privkey.pem gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: invalid radix64 character 2d skipped gpgsm: invalid radix64 character 3a skipped gpgsm: invalid radix64 character 2c skipped gpgsm: invalid radix64 character 2d skipped gpgsm: invalid radix64 character 3a skipped gpgsm: invalid radix64 character 2d skipped gpgsm: total number processed: 0 --disable-policy-checks joostvb@shamir:~% gpgsm --call-protect-tool --p12-import --store key.p12 gpg-protect-tool: encryptedData error at "bag.encryptedData.keyinfo", offset 79 gpg-protect-tool: error at "bag.encryptedData", offset 49 gpg-protect-tool: error parsing or decrypting the PKCS-12 file =head2 how you SHOULD do it How to add a secret key to the gpgme keystore : Follow instructions from http://www.gnupg.org/aegypten/development.en.html : * Create a Certificate Signing Request joostvb@shamir:~% cat tmp/script.assuan INPUT FD=4 OUTPUT FD=5 --armor GENKEY BYE EOF joostvb@shamir:~% cat tmp/parms.txt key-type: rsa key-length: 1024 key-usage: sign, encrypt name-dn: C=nl,O=UvT,OU=Testlab,CN=Joost van Baal test name-email: joostvb@uvt.nl joostvb@shamir:~% gpgsm --server <~/tmp/script.assuan 4<~/tmp/parms.txt 5>~/tmp/out.pem (asks for passphrase 3 times: aaaa) S KEY_CREATED P gpgsm: certificate request created OK OK closing connection * Create a CA joostvb@shamir:~% cp /usr/lib/ssl/misc/CA.pl tmp joostvb@shamir:~% cp /etc/ssl/openssl.cnf tmp joostvb@shamir:~/tmp% ./CA.pl -newca bbbb writing new private key to './demoCA/private/cakey.pem' subjectAltName=email:copy,email:joostvb@uvt.nl in ~/tmp/openssl.cnf * Sign the CSR joostvb@shamir:~/tmp% export SSLEAY_CONFIG=-config\ /home/joostvb/tmp/openssl.cnf joostvb@shamir:~/tmp% cp out.pem newreq.pem joostvb@shamir:~/tmp% ./CA.pl -sign Signed certificate is in newcert.pem * Import CA cert and signed certificate joostvb@shamir:~% gpgsm --import tmp/demoCA/cacert.pem gpgsm: total number processed: 1 gpgsm: imported: 1 joostvb@shamir:~% gpgsm --import tmp/newcert.pem gpgsm: total number processed: 1 gpgsm: imported: 1 joostvb@shamir:~% gpgsm --list-secret-keys Serial number: 00CA9D625569F968D0 Issuer: /CN=Joost van Baal CA/O=UvT/ST=Some-State/C=NL/EMail=joostvb@uvt.nl Subject: /CN=Joost van Baal test/OU=Testlab/O=UvT/C=nl aka: joostvb@uvt.nl validity: 2005-10-04 13:17:48 through 2006-10-04 13:17:48 Now it's in -rw-r----- 1 joostvb joostvb 669 Oct 4 15:06 5240703DE36BD1B4DA50D0A00CD3B3870FBE5BA6.key , in binary format =head2 dealing with s/mime emails joostvb@kovalevskaya:~/tmp% scp encrypt.mail signed.mail shamir: joostvb@shamir:~/bin% gpgsm --decrypt < ~/encrypt.mail gpgsm: DBG: ksba_cms_parse failed: End of file gpgsm: message decryption failed: End of file joostvb@shamir:~/bin% ./decrypt.py < ~/encrypt.mail Invocation of gpgme_op_decrypt: KSBA: End of file set smime_sign_command="openssl smime -sign -signer %c -inkey %k -passin stdin -in %f -certfile %i -outform DER" set smime_encrypt_command="openssl smime -encrypt %a -outform DER -in %f %c" RFC 3851 - Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.1 Message Specification gpgsm claims to understand CMS. "GPGSM automatically strips any S/MIME headers from the input, so it is valid to pass an entire MIME part to the INPUT pipe" http://article.gmane.org/gmane.comp.gnu.gnupg.users/4478 . From: Werner Koch gnupg.org> Subject: Re: Tutorial for gpgsm? Newsgroups: gmane.comp.gnu.gnupg.users Date: 2004-09-10 12:17:31 GMT . "gpgsm does not handle the S/MIME proper but only the CMS (pkcs#7) format." rip out base64 part: "signed.CMS-Base64" 56L, 4020C written joostvb@shamir:~% recode /Base64 < signed.CMS-Base64 > signed.CMS joostvb@shamir:~% file signed.CMS signed.CMS: data joostvb@shamir:~% gpgsm --verify signed.CMS gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: detached signature w/o data - assuming certs-only gpgsm: Signature made 2005-10-06 08:00:56 using certificate ID A9E656C7 gpgsm: invalid signature: message digest attribute does not match calculated one yeah, of course: we've removed the plain message part! joostvb@shamir:~% cp encrypt.mail encrypt.CMS-Base64 "encrypt.CMS-Base64" 17L, 1197C written joostvb@shamir:~% recode /Base64 < encrypt.CMS-Base64 > encrypt.CMS joostvb@shamir:~% gpgsm --decrypt encrypt.CMS gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: unsupported algorithm `1.2.840.113549.3.2' gpgsm: (this is the RC2 algorithm) gpgsm: message decryption failed: Unsupported algorithm .gnupg/trustlist.txt allows for colons in the fingerprint ! It is not possible to trust intermediate CA certificates; gpgsm always checks the entire chain of certificates. In general you should first import the root certificates and then down to the end user certificate. You may put all into one file and gpgsm will do the right thing in this case independend of the order. "2.6.4 Verifying a Message If the signature is a detached one, the server will inquire about the signed material and the client must provide it." This works: joostvb@shamir:~% openssl smime -decrypt -in encrypt.mail -inkey secret/ddd65994-key.pem -recip secret/ddd65994-cert.pem Content-Type: text/plain; charset=us-ascii Content-Disposition: inline encrypt -- Joost van Baal joostvb@uvt.nl http://abramowitz.uvt.nl/ (013-466-)3519 woensdag afwezig kamer CZ 218 ITS I&D Unix IRC: joostvb on #uvt at irc.uvt.nl This works too: joostvb@shamir:~% openssl smime -verify -in signed.mail Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable signed --=20 Joost van Baal joostvb@uvt.nl http://abramowitz.uvt.nl/ (013-466-)3519 woensdag afwezig kamer CZ 218 ITS I&D Unix IRC: joostvb on #uvt at irc.uvt.nl Verification successful (probably checks /etc/ssl/certs/uvt.pem ) joostvb@shamir:~% gpgsm --import /etc/ssl/certs/uvt.pem gpgsm: NOTE: THIS IS A DEVELOPMENT VERSION! gpgsm: It is only intended for test purposes and should NOT be gpgsm: used in a production environment or with production keys! Warning: using insecure memory! gpgsm: total number processed: 1 gpgsm: imported: 1 Issuer: /CN=SURFnet-PCA-Root-CA/OU=Policy Certification Authority/O=SURFnet/C=NL/EMail=SURFnet-PCA@surfnet.nl Subject: /CN=UvT-CA/OU=UvT Certification Authority/O=Universiteit van Tilburg/C=NL/EMail=UvT-CA@uvt.nl fingerprint: 87:26:EE:68:E2:6C:56:4E:77:54:D4:0D:40:19:78:87:52:DF:44:28 joostvb@shamir:~% vim .gnupg/trustlist.txt joostvb@shamir:~% kill -HUP 10779 still: joostvb@shamir:~% gpgsm --verify signed.CMS signed.body gpgsm: Signature made 2005-10-06 08:00:56 using certificate ID A9E656C7 gpgsm: invalid signature: message digest attribute does not match calculated one joostvb@banach:~/tmp% gpg --verify pgp-signed.sig pgp-signed.body gpg: Signature made Thu 06 Oct 2005 02:43:04 PM CEST using DSA key ID 88C6EDF6 gpg: please do a --check-trustdb gpg: Good signature from "Joost van Baal " gpg: aka "Joost van Baal " joostvb@banach:~/tmp% cat pgp-signed.body Content-Type: text/plain; charset=us-ascii Content-Disposition: inline signed Hrm, can't get a message to verify successfully with gpgsm... study CMS specs? =head2 smime emails and Mailman.Message See also "feeding a message from a file" in secure-list-patch.pod. joostvb@shamir:~% /usr/lib/mailman/bin/mailman-smime.py < signed.mail cms contains CMS part of message See also the way Mailman/Handlers/Moderate.py deals with detached PGP signatures in MIME stuff. joostvb@shamir:~% export GPG_TTY=`tty` joostvb@shamir:~% eval `gpg-agent --daemon --use-standard-socket` joostvb@shamir:~% /usr/lib/mailman/bin/mailman-smime.py < encrypt.mail cms contains crypted CMS stuff Invocation of gpgme_op_decrypt: GpgSM: Unsupported algorithm But: joostvb@shamir:~% ~/bin/decrypt.py < crypt This is my message. file crypt looks like: -----BEGIN ENCRYPTED MESSAGE----- MIAGCSqGSIb3DQEHA6CAMIACAQAxggEJMIIBBQIBADBwMGsxCzAJBgNVBAYTAkRF . Hrm, can we decrypt CMS blobs anyway? This gives the same: joostvb@shamir:~% ~/bin/decrypt.py < encrypt.CMS Invocation of gpgme_op_decrypt: GpgSM: Unsupported algorithm Perhaps we can grok and preprocess CMS with the cryptlib security toolkit 3.2.2 sept 2005 Peter Gutmann http://www.cypherpunks.to/~peter/manual.pdf ? http://trevp.net/cryptlibConverter/ It seems libksba should deal with CMS and ASN.1 stuff: "Libksba is a library to make the tasks of working with X.509 certificates, CMS data and related objects more easy. It provides a highlevel interface to the implemented protocols and presents the data in a consistent way." joostvb@banach:/usr...bksba/libksba-0.9.12/doc% make html =head2 dealing with encrypted smime mail: summary Message, displayed by mutt as: Date: Thu, 6 Oct 2005 10:02:38 +0200 From: Joost van Baal To: Joost van Baal Subject: encrypt Message-ID: <20051006080238.GA6519@banach.uvt.nl> Mime-Version: 1.0 Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m" Content-Disposition: attachment; filename="smime.p7m" Content-Transfer-Encoding: base64 User-Agent: Mutt/1.5.9i [-- The following data is S/MIME encrypted --] encrypt -- Joost van Baal joostvb@uvt.nl http://abramowitz.uvt.nl/ (013-466-)3519 woensdag afwezig kamer CZ 218 ITS I&D Unix IRC: joostvb on #uvt at irc.uvt.nl [-- End of S/MIME encrypted data. --] Running: c = core.Context() c.set_armor(1) c.set_protocol(pyme.util.gpgme.GPGME_PROTOCOL_CMS) try: c.op_decrypt(cipher, plain) plain.seek(0,0) print plain.read() except errors.GPGMEError, ex: print ex.getstring() on this gives: Invocation of gpgme_op_decrypt: KSBA: End of file (I do have GPG_AGENT_INFO and GPG_TTY set; I can encrypt and decrypt messages in PEM format.) Trimming off the headers, base64-decoding it: joostvb@shamir:~% recode /Base64 encrypt.body > encrypt.CMS Same: Invocation of gpgme_op_decrypt: KSBA: End of file However: joostvb@shamir:~% openssl smime -decrypt -in encrypt.mail -inkey secret/ddd65994-key.pem -recip secret/ddd65994-cert.pem Content-Type: text/plain; charset=us-ascii Content-Disposition: inline encrypt -- Hrm, gpgsm --list-secret-keys doesn't list this key! Let's enable generating emails with test-key: joostvb@banach:~/.smime% smime_keys add_chain keys/shamir certificates/shamir shamir.crt "bbbb" Error decrypting PKCS#7 structure 17759:error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch:x509_cmp.c:389: 17759:error:2107207F:PKCS7 routines:PKCS7_decrypt:private key does not match certificate:pk7_smime.c:409: Key is known as 1e405707 / fe4c64b5 with uvt-key, can sign, can encrypt, can sign+encrypt. =head2 implementing in openssl joostvb@shamir:~% openssl smime -verify < signed.mail > /dev/null Verification successful joostvb@shamir:~% openssl smime -verify < /etc/motd > /dev/null ; echo $? Error reading S/MIME message 4961:error:2107A087:PKCS7 routines:SMIME_read_PKCS7:no content type:pk7_mime.c:238: 3 joostvb@shamir:/usr/lib/mailman/bin% ./mailman-openssl-smime.py < ~/signed.mail openssl returned Verification successful joostvb@shamir:/usr/lib/mailman/bin% ./mailman-openssl-smime.py < /etc/motd ; echo joostvb@shamir:/usr/lib/mailman/bin% ./mailman-openssl-smime.py < /etc/motd =head1 CREATING A CA AND GENERATING KEYS AND CERTIFICATES * Setup the Certificate Authority joostvb@kovalevskaya:~/da...ssls/mailman-ssls/doc/CA% scp Makefile openssl.cnf shamir:CA/ joostvb@shamir:~/CA% vim openssl.cnf Adjust commonName 0.organizationName emailAddress Add subjectAltName=email:copy,email:joostvb+ca-test-signed@uvt.nl to [usr_cert] section. joostvb@shamir:~/CA% make init creates ca-cert.pem private/ca-key.pem * Generate personal key Check: joostvb@shamir:~% gpgsm --list-secret-keys we have 2 secret keys now. joostvb@shamir:~% gpgsm --server <~/tmp/script.assuan 4<~/tmp/parms.txt 5>~/tmp/test.csr pops up passphrase window. passphrase: a . tmp/test.csr created. Still 2 private keys in keystore. The private key is in some cache somewhere, likely. * Sign the csr. joostvb@shamir:~% mv tmp/test.csr CA joostvb@shamir:~/CA% make sign organizationalUnitName = Testlab commonName = Joost Test Key X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Subject Key Identifier: 58:E5:2E:F9:E0:DE:2E:5F:09:95:17:1D:9F:13:61:DB:33:A6:E6:3A X509v3 Authority Key Identifier: keyid:AF:05:31:C7:15:B6:E5:45:CE:35:78:B3:5D:78:5D:16:97:AB:1D:C0 DirName:/CN=Joost Test CA/O=uvt.nl/emailAddress=joostvb+ca-test@uvt.nl serial:C7:B0:9B:18:2D:D4:0D:E0 X509v3 Subject Alternative Name: email:joostvb+ca-test-signed@uvt.nl Certificate is to be certified until Oct 19 08:10:20 2015 GMT (3650 days) Write out database with 1 new entries Data Base Updated Certificate written to newcerts/01.pem * Importing in GPGME keystore joostvb@shamir:~% gpgsm --import CA/ca-cert.pem ... gpgsm: total number processed: 1 gpgsm: imported: 1 joostvb@shamir:~% gpgsm --import CA/newcerts/01.pem ... gpgsm: total number processed: 1 gpgsm: imported: 1 Now, gpgsm --list-secret-keys shows a 3rd secret key: Issuer: /CN=Joost Test CA/O=uvt.nl/EMail=joostvb+ca-test@uvt.nl Subject: /CN=Joost Test Key/OU=Testlab/O=UvT/C=nl aka: joostvb+ca-test-signed@uvt.nl * Optionally: signing a remotely generated key Generate a private key, following e.g. instructions in mutt.txt. joostvb@kovalevskaya:~% scp ~/tmp/joostvb-test-banach.csr shamir:CA/ joostvb@shamir:~/CA% make sign joostvb@kovalevskaya:~% scp shamir:CA/newcerts/02.pem ~/tmp/joostvb-test-banach.crt joostvb@kovalevskaya:~% scp ~/tmp/ca-cert.pem banach:.smime/shamir-joost-test-ca.pem Make keys known to your application. E.g. for mutt, do stuff like: joostvb@banach:~% smime_keys add_root .smime/shamir-joost-test-ca.pem Enter a label, name or description for this certificate: joost-test-ca-shamir joostvb@banach:~% smime_keys add_chain .smime/keys/joostvb-test-banach.key .smime/certificates/joostvb-test-banach.crt .smime/shamir-joost-test-ca.pem (If you make a mistake, clean up with: joostvb@banach:~% smime_keys remove 5b00650d.0 Removed certificate 5b00650d.0. Removed private key 5b00650d.0. ) Be sure to take a look at mutt.txt too! =head2 Generating S/MIME keypairs for SSLS lists joostvb@shamir:/var...n/lists/test-smime/smime% openssl genrsa -out key.pem 2048 joostvb@shamir:/var...n/lists/test-smime/smime% cat list.cfg [ req ] default_bits = 2048 default_keyfile = key.pem distinguished_name = req_distinguished_name attributes = req_attributes prompt = no [ req_distinguished_name ] C = NL O = Universiteit van Tilburg CN = Test List for S/MIME emailAddress = test-smime@securelist.surfnet.nl [ req_attributes ] joostvb@shamir:/var...n/lists/test-smime/smime% openssl req -new -newhdr -config list.cfg -key key.pem -days 3650 -sha1 -verify -out list.csr joostvb@shamir:/var...n/lists/test-smime/smime% cp list.csr ~/CA joostvb@shamir:~/CA% make sign joostvb@shamir:~/CA/newcerts% cp 03.pem /var/lib/mailman/lists/test-smime/smime/cert.pem root@shamir:/var...n/lists/test-smime/smime# cp ~joostvb/CA/ca-cert.pem ca.pem Now distribute the list certificate to the list members. Have the members feed it to their MUA: joostvb@banach:~% smime_keys add_cert tmp/cert.pem =head2 Conclusion We cannot import key.pem in GPGME keystore. We _can_ generate a key locally, have it signed remotely, and import and store the certificate. Very likely, this is just enough. =head1 Importing subscriber certificates If you don't wanna use the webinterface, run something like: root@shamir:~# cp ~joostvb/8d3f3edd.0 /var/lib/mailman/lists/test-smime/smime/j.e.vanbaal@uvt.nl.cert.pem =head1 FEEDING SMIME MAILS TO GPGME, TAKE 2 joostvb@shamir:~% gpgsm --import < CA/joostvb-test-banach.crt joostvb@shamir:~% gpgsm --verify signed-joostvb-banach.CMS signed-joostvb-banach.body [...] gpgsm: Signature made 2005-10-21 11:40:54 using certificate ID 090E2BFC gpgsm: invalid signature: message digest attribute does not match calculated one joostvb@shamir:~% openssl smime -verify -CAfile CA/ca-cert.pem < signed-joostvb-banach.mail Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable signed stuff --=20 Joost van Baal joostvb@uvt.nl http://abramowitz.uvt.nl/ (013-466-)3519 woensdag afwezig kamer CZ 218 ITS I&D Unix IRC: joostvb on #uvt at irc.uvt.nl Verification successful joostvb@shamir:~% recode /Base64 < signed-joostvb-banach.base64 > signed-joostvb-banach.CMS joostvb@shamir:~% vim signed-joostvb-banach.body shamir:CA/newcerts/01.pem -> banach:.smime/certificates/joostvb-test-shamir.crt joostvb@banach:~% smime_keys add_cert ~/.smime/certificates/joostvb-test-shamir.crt joostvb@shamir:~% gpgsm --decrypt < encrypt-joostvb-shamir.mail [...] gpgsm: DBG: ksba_cms_parse failed: End of file gpgsm: message decryption failed: End of file joostvb@shamir:~% gpgsm --decrypt < encrypt-joostvb-shamir.CMS gpgsm: unsupported algorithm `1.2.840.113549.3.2' gpgsm: (this is the RC2 algorithm) gpgsm: message decryption failed: Unsupported algorithm I cannot check this with openssl: no way to export the secret key from the GPGME-store to a .pem file. :( See also Date: Fri, 21 Oct 2005 15:03:46 +0200 From: Joost van Baal To: GnuPG Users Subject: handling S/MIME messages with gpgsm Message-ID: <20051021130346.GB4335@banach.uvt.nl> at http://lists.gnupg.org/pipermail/gnupg-users/2005-October/thread.html TODO: Once we have a working prototype with openssl, go and think about Werner Koch's reply. =head1 DOING A QUICK-AND-DIRTY PATCH UPGRADE In order to upgrade all lists, e.g. for adding new smime_ properties: - prepare Defaults.py from Defaults.py.in, and update from update (with-embedded @FOO@) - stop mailman on shamir - Install banach:/usr/local/src/mailman/mailman-2.1.6-ssls_2005-10-28/Mailman/{Defaults.py,mm_cfg.py.dist} on shamir. - Optional: upgrade shamir mm_cfg.py. - install Mailman/MailList.py, bin/update - run bin/update - start mailman =head1 NEW LIST PROPERTIES FOR SMIME We currently have: joostvb@kovalevskaya:~/da...sls/mailman-ssls/Mailman% grep gpg MailList.py self.gpgkeys = {} # for members self.gpgkeyids = {} # for members self.gpg_postings_allowed = mm_cfg.DEFAULT_GPG_POSTINGS_ALLOWED self.gpg_msg_distribution = mm_cfg.DEFAULT_GPG_MSG_DISTRIBUTION self.gpg_msg_sign = mm_cfg.DEFAULT_GPG_MSG_SIGN self.gpg_post_sign = mm_cfg.DEFAULT_GPG_POST_SIGN self.gpg_public_key = '' self.gpg_secret_key = '' self.gpg_passphrase = '' Where: gpg_postings_allowed: Is it allowed to send to this list postings which are encrypted with the GPG list key? TODO: (rename to "gpg_post_encrypt") gpg_post_sign: Should posts be GPG signed with an acknowledged subscriber key before being distributed? gpg_msg_distribution: Are subscribers allowed (or even forced) to upload their GPG public key in order to receive all messages encrypted? (rename to "gpg_distrib_encrypt") gpg_msg_sign: Should the server sign encrypted messages? (rename to "gpg_distrib_sign") Added: self.smime_ We don't need self.smime_public_key nor self.gpg_secret_key for now; just use files smime/{cert,key,ca}.pem. We don't need something like self.smime_keys and self.sime_keyids: have the list-key sign all member-keys. joostvb@kovalevskaya:~/da...sls/mailman-ssls/Mailman% scp SMIMEUtils.py root@shamir:/usr/lib/mailman/Mailman/ joostvb@shamir:/usr/lib/mailman/bin% ./mailman-openssl-smime.py < ~/encrypt.mail tail -f /var/log/mailman/gpg joostvb@kovalevskaya:~/da...an-ssls/Mailman/Handlers% scp Moderate.py root@shamir:/var/lib/mailman/Mailman/Handlers/ root@shamir:~# newlist test-smime j.e.vanbaal@uvt.nl joostvb@shamir:/usr/lib/mailman/bin% PYTHONSTARTUP=~/PYTHONSTARTUP python Python 2.3.5 (#2, Sep 4 2005, 22:01:42) [GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> dir(mlist) [...] >>> mlist.smime_distrib_encrypt False >>> print mlist.members {'teun.nijssen@uvt.nl': 0, 'sebas@uvt.nl': 0, 'j.e.vanbaal@uvt.nl': 0, 'guus+securelist@sliepen.eu.org': 0, 'w.s.l.dankers@uvt.nl': 'W.S.L.Dankers@uvt.nl'} >>> mlist.getSMIMEKey('sebas@uvt.nl') >>> from Mailman import SMIMEUtils >>> sm = SMIMEUtils.SMIMEHelper(mlist) >>> sm.importKey('joe@example.com', 'foo') =head1 GNUPG2 DEBIAN PACKAGE joostvb@banach:/usr...pg2/1.9.19/gnupg2-1.9.19% debuild --linda -uc -us The following NEW packages will be installed: hotplug libbz2-dev libccid libldap2-dev libpcsclite-dev libpcsclite1 pcscd usbutils libopenct1 libopensc1 libscam1 libssl-dev zlib1g-dev check library versino dependencies in INSTALL. W: gnupg2 source: maintainer-script-lacks-debhelper-token debian/gnupg2.postinst W: gnupg2 source: maintainer-script-lacks-debhelper-token debian/gnupg2.postrm E: gpgsm: debian-changelog-file-uses-obsolete-national-encoding at line 475 E: gnupg2: suidregister-used-in-maintainer-script postinst W: gpgsm: binary-without-manpage gpgsm W: gpgsm: binary-without-manpage gpgsm-gencert.sh W: gpgsm: binary-without-manpage scdaemon W: gnupg2: binary-without-manpage addgnupghome W: gnupg2: binary-without-manpage gpg2 W: gnupg2: binary-without-manpage gpgconf W: gnupg2: binary-without-manpage gpgv2 W: gnupg2: binary-without-manpage kbxutil W: gnupg2: binary-without-manpage watchgnupg W: gnupg-agent: binary-without-manpage gpg-agent Added follow-up to http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=306890 The following packages will be REMOVED: hotplug libbz2-dev libccid libldap2-dev libopenct1 libopensc1 libopensc1-dev libpcsclite-dev libpcsclite1 libscam1 libssl-dev pcscd usbutils zlib1g-dev =head1 TESTING =head2 test lists The test-smime-secure list has settings: smime_post_encrypt Yes (encrypt post to listkey) smime_distrib_encrypt Force (distribute encypted) smime_post_sign Force (should posts be signed) smime_distrib_sign Yes (distribute signed) The test-smime list has settings: smime_post_encrypt Yes smime_distrib_encrypt Yes smime_post_sign Force The test-vanilla list has settings: smime_* No =head2 test log Using test-smime list: joostvb@shamir:/var/lib/mailman/bin% ./mailman-openssl-smime.py < ~/signed.mail S/MIME verify OK (test-smime trusts joostvb@shamir:CA/ apparently) joostvb@shamir:/var/lib/mailman/bin% ./mailman-openssl-smime.py < ~/encrypt-test-smime.mail sm.decryptMessage returned: %s Content-Type: text/plain; charset=us-ascii Content-Disposition: inline geheimpje =head1 CONFIGURING SMIME SETTINGS root@shamir:~# config_list -o - test-smime-secure > /tmp/test-smime-secure root@shamir:~# vi /tmp/test-smime-secure root@shamir:~# config_list -i /tmp/test-smime-secure test-smime-secure =head1 BUILDING S/MIME MAILS FROM WITHIN MAILMAN =head2 DEBUGGING ENCRYPTION This works just fine: joostvb@shamir:~% openssl smime -encrypt /var/lib/mailman/lists/test-smime/smime/j.e.vanbaal+20051121@uvt.nl.cert.pem < /etc/motd > ~/tmp/encrypt-to-j.e.vanbaal+20051121 joostvb@banach:~% openssl smime -decrypt -recip .smime/certificates/joostvb+20051121.crt -inkey ~/.smime/keys/joostvb+20051121.key < tmp/encrypt-to-j.e.vanbaal+20051121 Sticking it in Message-ID: <20051121161707.GB4335@banach.uvt.nl> and displaying it using mutt does NOT work: "no recipient matches certificate" Neither does sending a bare or signed mail to test-smime. joostvb@banach:~% openssl smime -encrypt .smime/certificates/joostvb+20051121.crt < tmp/input.mime > ~/tmp/encrypt-to-j.e.vanbaal+20051121.from-mime we seem to need to keep mime-* and content-* in our input, like: Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable joostvb@banach:~% openssl smime -encrypt -des3 .smime/certificates/joostvb+20051121.crt < tmp/mail.non-ascii > ~/tmp/encrypt-to-j.e.vanbaal+20051121.non-ascii Nope: [-- OpenSSL output follows (current time: Tue 22 Nov 2005 12:55:38 PM CET) --] Verification failure 1023:error:21075071:PKCS7 routines:PKCS7_verify:wrong content type:pk7_smime.c:166: [-- End of OpenSSL output --] [-- The following data is S/MIME signed --] Terwijl het voeren van rauw encrypted spul: Content-Type: application/x-pkcs7-mime; name="smime.p7m" Content-Transfer-Encoding: base64 MIICcgYJKoZIhvcNAQcDoIICYzCCAl8CAQAxggFxMIIBbQIBADBVMFAxFjAUBgNV aan openssl smime -decrypt -inkey .smime/keys/joostvb+20051121.key -recip .smime/certificates/joostvb+20051121.crt < _wel_ werkt! Muttrc heeft "-inform DER" in -decrypt invokatie. NB: Mutt 1.5.11 grokt dit, na hacken van Content-Type, _wel_! =head2 DEBUGGING SIGNING This generates a MIME-like message: joostvb@banach:~% openssl smime -sign -signer ~/.smime/certificates/joostvb+20051121.crt -inkey ~/.smime/keys/joostvb+20051121.key -text < /etc/motd.old > ~/tmp/mail.signed it adds ^M to plain ascii files, saves in MIME attachment "Content-Type: text/plain". Seems to be the way it should be: mutt deals fine with it. See Date: Tue, 22 Nov 2005 11:17:22 +0100; Message-ID: <20051121124951.GY4335@banach.uvt.nl> "-text" adds "Content-Type: text/plain" MIME header. If no "-text" is passed _no_ Content-Type header is present in data! Hrm, it seems we need to add a content-type and/or content-transfer-encoding header to the "-encrypt" input file. See "sub smime_sign" in sympa/sympa-5.1/src/tools.pl openssl 0.9.7e-3sarge1: joostvb@banach:~% openssl smime -encrypt ~/.smime/certificates/joostvb+20051121.crt < /etc/issue | head MIME-Version: 1.0 Content-Disposition: attachment; filename="smime.p7m" Content-Type: application/x-pkcs7-mime; name="smime.p7m" Content-Transfer-Encoding: base64 MIIJSgYJKoZIhvcNAQcDoIIJOzCCCTcCAQAxggFxMIIBbQIBADBVMFAxFjAUBgNV Unpacking libssl0.9.8 (from .../libssl0.9.8_0.9.8a-4a0.sarge.1_i386.deb) ... Preparing to replace openssl 0.9.7e-3sarge1 (using .../openssl_0.9.8a-4a0.sarge.1_i386.deb) ... joostvb@banach:~% openssl smime -encrypt ~/.smime/certificates/joostvb+20051121.crt < /etc/issue | head MIME-Version: 1.0 Content-Disposition: attachment; filename="smime.p7m" Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m" Content-Transfer-Encoding: base64 MIIJSgYJKoZIhvcNAQcDoIIJOzCCCTcCAQAxggFxMIIBbQIBADBVMFAxFjAUBgNV =head2 DEBUGGING SIGNING + ENCRYPTING openssl smime -sign -signer ~/.smime/certificates/joostvb+20051121.crt -inkey ~/.smime/keys/joostvb+20051121.key -text < /etc/motd.old | openssl smime -encrypt ~/.smime/certificates/joostvb+20051121.crt > ~/tmp/mail.signed+encrypt Gives: "wrong content type" If Content-Type hacked: "no recipient matches certificate" toevoegen "-des3" maakt niks uit. Met nieuwe mutt werkt t wel, na hacken van Content-Type. =head1 STATUS / TODO =head2 status We kinda can: export keys with export.py; encrypt a .pem message with simple.py. We kinda can: decrypt a .pem message, using decrypt.py. We kinda can: generate a certificate request, with genkey.py. We kinda can: generate a certified secret key, and manually store it in our keystore. We kinda can: set up a test CA, generate certificates from certificate signing requests. We have: a way to fetch raw CMS blobs from messages in text files, using the Mailman object interface, in the mailman-smime.py script. (BTW: our server it not used that much; it seems we don't have to be extremely careful and can do some testing with the live system). We can verify and decrypt smime messages in the Mailman framework, using openssl(1) We can configure lists to accept only posts, S/MIME signed with key signed by trusted CA. We can configure lists to decrypt posts, encrypted to list-key. We offer a webinterface for subscribers to upload their signed keys in .pem format. Sending bare mails to test-smime: OK (held for moderation) Sending correctly signed mails to test-smime: OK (distributed) =head2 todo Volunteers: @uvt: Wessel, Guus (RSN) (none other) See mailman-ssls/README.GPG for thing to do. =head1 VERSION Maintained using darcs on http://non-gnu.uvt.nl/repos/mailman-ssls . =cut