### Build and Install M2Crypto from Source Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Use these commands to build and install M2Crypto after extracting the source archive. Ensure OpenSSL is installed in the default location. ```bash $ tar zxf m2crypto-.tar.gz $ cd m2crypto- $ python setup.py build $ python setup.py install ``` -------------------------------- ### Install M2Crypto Wheel on Windows Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Installs the generated M2Crypto wheel file. Ensure you replace the filename with the actual generated file. If issues arise, try installing 'wheel' first. ```bash pip install M2Crypto-0.35.2-cp38-cp38-win_amd64.whl ``` -------------------------------- ### Run M2Crypto Tests Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md If setuptools is installed, you can run the library's tests using this command. ```bash $ python -munittest discover -v tests ``` -------------------------------- ### Install M2Crypto with MINGW Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Instructions for building M2Crypto using MINGW, potentially requiring the '-cmingw32' parameter for setup.py build. ```bash setup.py build -cmingw32 ``` -------------------------------- ### Install OpenSSL and SWIG on macOS Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Installs OpenSSL and SWIG using Homebrew on macOS. These are prerequisites for building M2Crypto on this platform. ```bash brew install openssl && brew install swig ``` -------------------------------- ### Generate Installable Files for M2Crypto on Windows Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Generates wheel, wininst, and msi installers for M2Crypto. These files are placed in the 'dist' directory. ```python python.exe setup.py bdist_wheel bdist_wininst bdist_msi ``` -------------------------------- ### Build M2Crypto with OpenSSL on Windows Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Builds M2Crypto, specifying the OpenSSL installation directory and bundling DLLs. Replace the OpenSSL path with your actual installation directory. ```bash python setup.py build --openssl="C:\Program Files\OpenSSL-Win64" --bundledlls ``` -------------------------------- ### Install Chocolatey Package Manager on Windows Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Installs the Chocolatey package manager using PowerShell. This is a prerequisite for installing other tools like swig. ```powershell Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) ``` -------------------------------- ### Install pywin32 Dependency on Windows Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Installs the pywin32 Python package. It's recommended to install 'wheel' first if you encounter issues. Use 'py -[version] -m pip install [module]' to target specific Python installations. ```python pip install pywin32 ``` ```python pip install wheel ``` -------------------------------- ### Install SWIG using Chocolatey on Windows Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Installs the SWIG tool using the Chocolatey package manager. SWIG is a dependency for M2Crypto. ```powershell choco install -r -y swig ``` -------------------------------- ### Install M2Crypto on macOS with Homebrew OpenSSL Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Installs M2Crypto, configuring build flags to use OpenSSL installed via Homebrew. This is necessary on newer macOS versions that do not include OpenSSL. ```bash LDFLAGS="-L$(brew --prefix openssl)/lib" \ CFLAGS="-I$(brew --prefix openssl)/include" \ SWIG_FEATURES="-I$(brew --prefix openssl)/include" \ pip install m2crypto ``` -------------------------------- ### HTTPS via Proxy with Engine Support Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ssl.md Configures an SSL context with an OpenSSL Engine for tunneled HTTPS requests through a proxy. This example shows loading a dynamic engine and setting it as the default, then loading certificate and private key from a smartcard. ```python from M2Crypto import Engine, SSL, httpslib, m2 # Load the dynamic engine and configure it to use the PKCS#11 module Engine.load_dynamic() with Engine.Engine('dynamic') as e: e.ctrl_cmd_string('SO_PATH', '/path/to/engine.so') e.ctrl_cmd_string('ID', 'pkcs11') e.ctrl_cmd_string('LIST_ADD', '1') e.ctrl_cmd_string('LOAD', None) e.ctrl_cmd_string('MODULE_PATH', '/path/to/pkcs11/module.so') # WARNING: this sets a *process-wide* OpenSSL default e.set_default(m2.ENGINE_METHOD_RSA) # Load the client certificate and private key from the smartcard # Certificate loading is engine-specific; many PKCS#11 engines # only expose private keys. cert = e.load_certificate('pkcs11:object=MyCert') # Fallback if the engine does not support certificate loading: # cert = X509.load_cert('client.pem') # PIN will be collected via the external engine’s UI # alternative is to use `pin=os.environ['PKCS11_PIN']`, # but the whole thing is highly engine-specific pkey = e.load_private_key('pkcs11:object=MyKey', pin=None) # Create an SSL context and configure it to use the client certificate ctx = SSL.Context('tls') ctx.load_verify_locations(capath='/etc/ssl/certs') ctx.set_verify(SSL.verify_peer, depth=9) ctx.load_cert_chain(cert, pkey) # Create a ProxyHTTPSConnection and use it to make a request # Ensure you do not call con.connect() manually if you use methods that trigger it (like request()) con = httpslib.ProxyHTTPSConnection('proxy.example.com', 8080, ssl_context=ctx) # Absolute URL is required for proxy requests con.putrequest('GET', 'https://target.example.com/path') con.endheaders() # con.connect() is called implicitly by endheaders/send, # or you can call it manually if you haven't sent headers yet. # Do NOT call it twice. res = con.getresponse() print(res.read()) except EngineError as e: print("Engine failure:", e) raise except SSL.SSLError as e: print("TLS failure:", e) raise ``` -------------------------------- ### S/MIME Verification Error Example Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Demonstrates a typical traceback when S/MIME verification fails due to a self-signed certificate. ```python from M2Crypto import SMIME s = SMIME.SMIME() # Assuming 'recipient.pem' is loaded and configured in 's' p7 = SMIME.smime_load_pkcs7('sign.p7')[0] # Simplified for error context v = s.verify(p7) print(v) ``` -------------------------------- ### Build M2Crypto with Custom OpenSSL Prefix Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md When OpenSSL is installed in a non-standard location, specify the prefix using the --openssl option during the build process. ```bash $ python setup.py build --openssl=/usr/local ``` -------------------------------- ### Python HTTPS Request with M2Crypto Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/demo/Zope27/INSTALL.txt Example of making an HTTPS request to a Zope server using M2Crypto's m2urllib. It demonstrates opening a URL, adding a header, reading the response, and closing the connection. ```python >>> from M2Crypto import Rand, SSL, m2urllib >>> url = m2urllib.FancyURLopener() >>> url.addheader('Connection', 'close') >>> u = url.open('https://127.0.0.1:8443/') send: 'GET / HTTP/1.1\r\nHost: 127.0.0.1:8443\r\nAccept-Encoding: identity\r\nUser-agent: Python-urllib/1.15\r\nConnection: close\r\n\r\n' reply: 'HTTP/1.1 200 OK\r\n' header: Server: ZServerSSL/0.12 header: Date: Sun, 28 Sep 2003 09:40:14 GMT header: Content-Length: 3055 header: Etag: header: Content-Type: text/html header: Connection: close >>> while 1: ... data = u.read() ... if not data: break ... print(data) ... [blah blah blah]

Go directly to the Zope Management Interface if you'd like to start working with Zope right away. NOTE: Some versions of Microsoft Internet Explorer, (specifically IE 5.01 and early versions of IE 5.5) may have problems displaying Zope management pages. If you cannot view the management pages, try upgrading your IE installation to the latest release version, or use a different browser.

  • Find out about Zope Corporation, the publishers of Zope.

  • >>> u.close() >>> ``` -------------------------------- ### HTTPS with PKCS#11 Engine Support Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ssl.md Demonstrates loading a PKCS#11 engine, certificate, and private key to establish an HTTPS connection without a proxy. Ensure the engine and module paths are correctly specified. ```python from M2Crypto import SSL, httpslib, m2, Engine slot_id = "slot_00" # 'loader' is the dynamic engine used to load the shared object loader = Engine.load_dynamic_engine("pkcs11", "c:/tests_python/pkcs11.dll") # 'pkcs11' is the actual engine instance we want to use with Engine.Engine("pkcs11") as pkcs11: # Note: some PKCS#11 engines require MODULE_PATH to be set # before ENGINE_init(); engine behavior may vary. pkcs11.ctrl_cmd_string("MODULE_PATH", "C:/WINDOWS/system32/OcsCryptoki.dll") # We do not call set_default(); the key and cert are bound # explicitly to the SSL context instead. # Load from the PKCS#11 engine, NOT the loader cert = pkcs11.load_certificate(slot_id) # PIN will be collected via the external engine’s UI # alternative is to use `pin=os.environ['PKCS11_PIN']`, # but the whole thing is highly engine-specific key = pkcs11.load_private_key(slot_id) ctx = SSL.Context('tls') # Use the loaded objects m2.ssl_ctx_use_x509(ctx.ctx, cert.x509) m2.ssl_ctx_use_pkey_privkey(ctx.ctx, key.pkey) ctx.set_verify(SSL.verify_none, depth=1) con = httpslib.HTTPSConnection('url', 443, ssl_context=ctx) con.request("GET", "/") resp = con.getresponse() ``` -------------------------------- ### Establish a Secure SSL Client Connection Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ssl.md This snippet shows how to create an SSL context, set verification options, load CA certificates, and establish a secure connection to a server. It's crucial for implementing secure clients. ```python ctx = SSL.Context() ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9) if ctx.load_verify_locations('ca.pem') != 1: raise Exception('No CA certs') s = SSL.Connection(ctx) s.connect(server_address) # Normal protocol (for example HTTP) commands follow ``` -------------------------------- ### Launch Zope Server with SSL Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/demo/Zope27/INSTALL.txt Command to launch the Zope server with SSL enabled. Ensure you are in the instance home directory. ```bash $ /bin/runzope ``` -------------------------------- ### Create SSL Directory Symlink Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/demo/Zope27/INSTALL.txt Workaround for a bug in Zope 2.7.0b2 where INSTANCE_HOME might point to the wrong directory. This creates a symbolic link to the correct SSL directory. ```bash $ (cd ; ln -s /ssl) ``` -------------------------------- ### Test WebDAV-over-HTTPS with Cadaver Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/demo/Zope27/INSTALL.txt Demonstrates connecting to Zope via WebDAV over HTTPS using the 'cadaver' tool. It shows the process of accepting an untrusted certificate and authenticating. ```bash $ cadaver https://localhost:8443/ WARNING: Untrusted server certificate presented: Issued to: M2Crypto, SG Issued by: M2Crypto, SG Do you wish to accept the certificate? (y/n) y Authentication required for Zope on server `localhost': Username: admin Password: dav:/> ls Listing collection `/': succeeded. Coll: Control_Panel 0 Sep 28 00:38 Coll: temp_folder 0 Sep 28 17:30 acl_users 0 Sep 28 00:38 browser_id_manager 0 Sep 28 00:38 error_log 0 Sep 28 00:38 index_html 28 Sep 28 00:39 session_data_manager 0 Sep 28 00:38 standard_error_message 1189 Sep 28 00:39 standard_html_footer 18 Sep 28 00:39 standard_html_header 82 Sep 28 00:39 standard_template.pt 282 Sep 28 00:39 dav:/> quit Connection to `localhost' closed. $ ``` -------------------------------- ### Create a New CA Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md Execute this command to initiate the creation of a new Certificate Authority. You will be prompted to enter details for the CA's distinguished name and set a passphrase for its private key. ```bash ./CA.pl -newca A certificate filename (or enter to create) Making CA certificate ... Using configuration from openssl.cnf Generating a 1024 bit RSA private key ............++++++ ......................++++++ writing new private key to './demoCA/private/cakey.pem' Enter PEM pass phrase: Verifying password - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:SG State or Province Name (full name) [Some-State]:. Locality Name (eg, city) []:.. Organization Name (eg, company) [Internet Widgits Pty Ltd]:DemoCA Organizational Unit Name (eg, section) []:. Common Name (eg, YOUR name) []:DemoCA Certificate Master Email Address []:certmaster@democa.dom ``` -------------------------------- ### Display Certificate Request and Private Key Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md Display the content of the `newreq.pem` file, which contains both the certificate request and its corresponding private key. The private key is encrypted. ```bash cat newreq.pem ``` ```text -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,41B2874DF3D02DD4 ``` -------------------------------- ### Export Private Key and Certificate to PKCS#12 Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Use this command to transform a recipient's private key and certificate into PKCS#12 format for use with S/MIME clients. ```default openssl pkcs12 -export -in recipient.pem -inkey recipient_key.pem \ -name "S/MIME Recipient" -out recipient.p12 Enter Export Password: Verifying password - Enter Export Password: ``` -------------------------------- ### Generate S/MIME Signed Message Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Demonstrates how to create an S/MIME-signed message using M2Crypto. Requires a signer key and certificate. The message buffer is consumed by the sign operation. ```python from M2Crypto import BIO, Rand, SMIME def makebuf(text): return BIO.MemoryBuffer(text) # Make a MemoryBuffer of the message. buf = makebuf(b'a sign of our times') # Seed the PRNG. Rand.load_file('randpool.dat', -1) # Instantiate an SMIME object; set it up; sign the buffer. s = SMIME.SMIME() s.load_key('signer_key.pem', 'signer.pem') p7 = s.sign(buf, SMIME.PKCS7_DETACHED | SMIME.PKCS7_TEXT) ``` -------------------------------- ### Output S/MIME Signed Message in Mail-Friendly Format Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Renders a PKCS #7 signature blob in a mail-friendly format. The message buffer needs to be recreated after signing. Saves the PRNG state. ```python # Recreate buf. buf = makebuf(b'a sign of our times') # Output p7 in mail-friendly format. out = BIO.MemoryBuffer() out.write(b'From: sender@example.dom\n') out.write(b'To: recipient@example.dom\n') out.write(b'Subject: M2Crypto S/MIME testing\n') s.write(out, p7, buf) print(out.read().decode()) # Save the PRNG's state. Rand.save_file('randpool.dat') ``` -------------------------------- ### Load and Verify PKCS#7 Blob Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Loads a PKCS#7 blob from a memory buffer and verifies it. This is useful for checking the integrity of signed S/MIME messages. ```python p7_bio = BIO.MemoryBuffer(out) p7, data = SMIME.smime_load_pkcs7_bio(p7_bio) v = s.verify(p7) print(v) ``` -------------------------------- ### Connect to M2Crypto XML-RPC Server Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/demo/Zope27/INSTALL.txt Connects to an SSL-secured XML-RPC server using M2Crypto and prints its property map. Ensure the server is running and accessible at the specified URL. ```python from M2Crypto.m2xmlrpclib import Server, SSL_Transport zs = Server('https://127.0.0.1:8443/', SSL_Transport()) print(zs.propertyMap()) ``` -------------------------------- ### Generate S/MIME Signing Certificate Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Generates a 1024-bit RSA key pair and a self-signed X.509 certificate for S/MIME signing. The certificate is valid for 365 days. The private key is saved as `privkey.pem` and the certificate as `signer.pem`. ```default openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out signer.pem Using configuration from /usr/local/pkg/openssl/openssl.cnf Generating a 1024 bit RSA private key ..++++++ ....................++++++ writing new private key to 'privkey.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:SG State or Province Name (full name) [Some-State]:. Locality Name (eg, city) []:. Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto Organizational Unit Name (eg, section) []:. Common Name (eg, YOUR name) []:S/MIME Sender Email Address []:sender@example.dom ``` -------------------------------- ### Verify S/MIME Signature Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Sets up an SMIME object to verify a signature. Requires loading the signer's certificate and CA certificate into an X509 store. ```python from M2Crypto import SMIME, X509 # Instantiate an SMIME object. s = SMIME.SMIME() # Load the signer's cert. x509 = X509.load_cert('signer.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Load the signer's CA cert. In this case, because the signer's # cert is self-signed, it is the signer's cert itself. st = X509.X509_Store() st.load_info('signer.pem') s.set_x509_store(st) ``` -------------------------------- ### Generate a Certificate Request Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md Use this command to create a new certificate signing request (CSR) and its associated private key. You will be prompted for details to include in the request and a passphrase for the private key. ```bash ./CA.pl -newreq Using configuration from openssl.cnf Generating a 1024 bit RSA private key ..........++++++ ..............++++++ writing new private key to 'newreq.pem' Enter PEM pass phrase: Verifying password - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:SG State or Province Name (full name) [Some-State]:.. Locality Name (eg, city) []:. Organization Name (eg, company) [Internet Widgits Pty Ltd]:M2Crypto Organizational Unit Name (eg, section) []:. Common Name (eg, YOUR name) []:localhost Email Address []:admin@server.example.dom Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Request (and private key) is in newreq.pem ``` -------------------------------- ### Verify Signing Certificate Content Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Displays the detailed content of the generated S/MIME signing certificate (`signer.pem`) using OpenSSL. This command verifies the certificate's issuer, validity period, subject, and public key information. ```default openssl x509 -noout -text -in signer.pem Certificate: Data: Version: 3 (0x2) Serial Number: 0 (0x0) Signature Algorithm: md5WithRSAEncryption Issuer: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom Validity Not Before: Mar 24 12:56:16 2001 GMT Not After : Mar 24 12:56:16 2002 GMT Subject: C=SG, O=M2Crypto, CN=S/MIME Sender/Email=sender@example.dom Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:a9:d6:e2:b5:11:3b:ae:3c:e2:17:31:70:e1:6e: 01:f4:19:6d:bd:2a:42:36:2b:37:34:e2:83:1d:0d: 11:2e:b4:99:44:db:10:67:be:97:5f:5b:1a:26:33: 46:23:2f:95:04:7a:35:da:9d:f9:26:88:39:9e:17: cd:3e:eb:a8:19:8d:a8:2a:f1:43:da:55:a9:2e:2c: 65:ed:04:71:42:ce:73:53:b8:ea:7e:c7:f0:23:c6: 63:c5:5e:68:96:64:a7:b4:2a:94:26:76:eb:79:ea: e3:4e:aa:82:09:4f:44:87:4a:12:62:b5:d7:1f:ca: f2:ce:d5:ba:7e:1f:48:fd:b9 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:C4:F0:83:1A:2B:C7:99 X509v3 Authority Key Identifier: keyid:29:FB:38:B6:BF:E2:40:BB:FF:D5:71:D7:C4:F0:83:1A:2B:C7:99 DirName:/C=SG/O=M2Crypto/CN=S/MIME Sender/Email=sender@example.dom serial:00 X509v3 Basic Constraints: CA:TRUE Signature Algorithm: md5WithRSAEncryption 68:c8:6b:1b:fa:7c:9a:39:35:76:18:15:c9:fd:89:97:62:db: 7a:b0:2d:13:dd:97:e8:1b:7a:9f:22:27:83:24:9d:2e:56:ec: 97:89:3c:ef:16:55:80:5a:18:7c:22:d0:f6:bb:e3:a4:e8:59: 30:ff:99:5a:93:3e:ea:bc:ee:7f:8d:d6:7d:37:8c:ac:3d:74: 80:ce:7a:99:ba:27:b9:2a:a3:71:fa:a5:25:ba:47:17:df:07: 56:96:36:fd:60:b9:6c:96:06:e8:e3:7b:9f:4b:6a:95:71:a8: 34:fc:fc:b5:88:8b:c4:3f:1e:24:f6:52:47:b2:7d:44:67:d9: 83:e8 ``` -------------------------------- ### View Signed Certificate Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md Display the content of the newly signed certificate file using the cat command. This allows verification of the certificate details. ```bash cat newcert.pem ``` -------------------------------- ### Displaying Unencrypted Private Key Content Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md After removing encryption, you can view the content of the unencrypted private key file using the cat command. ```bash cat newkey2.pem ``` -------------------------------- ### Rename Private Key File Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Renames the generated private key file `privkey.pem` to `signer_key.pem` for clarity, indicating it's the private key companion to `signer.pem`. ```default mv privkey.pem signer_key.pem ``` -------------------------------- ### Verify S/MIME Signed Data Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Loads and verifies a PKCS7 signed data object. Requires a SMIME object initialized with a certificate stack. ```python from M2Crypto import SMIME s = SMIME.SMIME() # Assuming 'signer.pem' is loaded and configured in 's' p7, data = SMIME.smime_load_pkcs7('sign.p7') v = s.verify(p7, data) print(v) print(data) print(data.read()) ``` -------------------------------- ### Sign Message with S/MIME Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Signs a message buffer using S/MIME. Requires loading the signer's private key and certificate, and seeding the PRNG. ```python from M2Crypto import BIO, Rand, SMIME, X509 def makebuf(text): return BIO.MemoryBuffer(text) # Make a MemoryBuffer of the message. buf = makebuf(b'a sign of our times') # Seed the PRNG. Rand.load_file('randpool.dat', -1) # Instantiate an SMIME object. s = SMIME.SMIME() # Load signer's key and cert. Sign the buffer. s.load_key('signer_key.pem', 'signer.pem') p7 = s.sign(buf) ``` -------------------------------- ### Decode Certificate Request Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md Use the openssl command to decode a certificate request and view its details. This command requires the certificate request file as input. ```bash openssl req -text -noout < newreq.pem ``` -------------------------------- ### Rename Private Key File Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Rename the generated private key file to a more descriptive name. This is a standard shell command. ```default mv privkey.pem recipient_key.pem ``` -------------------------------- ### Clone M2Crypto Repository Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/INSTALL.md Clones the M2Crypto source code from its Git repository. Alternatively, download the source archive from SourceHut. ```bash git clone https://git.sr.ht/~mcepl/m2crypto ``` -------------------------------- ### Display CA Private Key Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md View the content of the CA's private key file, which is stored in PEM format. This key is encrypted with a passphrase. ```bash cat demoCA/private/cakey.pem ``` ```text -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,19973A9DBBB601BA eOq9WFScNiI4/UWEUaSnGTKpJv2JYuMD3HwQox2Q3Cd4zGqVjJ6gF3exa5126cKf X/bMVnwbPpuFZPiAIvaLyCjT6pYeXTBbSzs7/GQnvEOv+nYnDUFWi0Qm92qLk0uy pFi/M1aWheN3vir2ZlAw+DW0bOOZhj8tC7Co7lMYb0YE271b6/YRPZCwQ3GXAHUJ +aMYxlUDrK45aCUa/1CZDzTgk7h9cDgx2QJSIvYMYytCfI3zsuZMJS8/4OXLL0bI lKmAc1dwB3DqGJt5XK4WJesiNfdxeCNEgAcYtEAgYZTPIApU+kTgTCIxJl2nMW7j ax+Q1z7g+4MpgG20WD633D4z4dTlDdz+dnLi0rvuvxiwt+dUhrqiML1tyi+Z6EBH jU4/cLBWev3rYfrlp4x8J9mDte0YKOk3t0wQOHqRetTsIfdtjnFp/Hu3qDmTCWjD z/g7PPoO/bg/B877J9WBPbL/1hXXFYo88M+2aGlPOgDcFdiOqbLb2DCscohMbbVr A4mgiy2kwWfIE73qiyV7yyG8FlRvr1iib+jbT3LTGf743utYAAs7HNGuOUObhoyt jYvBD7ACn35P5YX7KTqvqErwdijxYCaNBCnvmRtmYSaNw9Kv1UJTxc5Vx7YLwIPk E9KyBgKI7vPOjWBZ27+zOvNycmv1ciNtpALAw4bWtXnhCDVTHaVDy34OkheMzNCg 2cjcBFzOkMIjcI03KbTQXOFIQGlsTWXGzkNf/zBQ+KksT1MCj+zBXSCvlDASMckg kef21pGgUqPF14gKGfWX3sV4bjc1vbrRwq6zlG3nMuYqR5MtJJY9eQ== -----END RSA PRIVATE KEY----- ``` -------------------------------- ### Decrypting and Re-encrypting a Private Key Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md Use this command to remove encryption from a private key, making it suitable for unattended server use. Ensure your security policy permits this action. ```bash openssl rsa < newkey.pem > newkey2.pem read RSA key Enter PEM pass phrase: writing RSA key ``` -------------------------------- ### Create DER Encoding of Certificate Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Convert a PEM-encoded certificate to DER format, which is required for importing into some S/MIME clients. ```default openssl x509 -inform pem -outform der -in signer.pem -out signer.der ``` -------------------------------- ### Sign Certificate Request with CA Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md Sign a certificate request using a Certificate Authority (CA) script. This process involves providing the CA's passphrase and confirming the signing operation. The signed certificate is output to a file. ```bash ./CA.pl -sign Using configuration from openssl.cnf Enter PEM pass phrase: Check that the request matches the signature Signature ok The Subjects Distinguished Name is as follows countryName :PRINTABLE:'SG' organizationName :PRINTABLE:'M2Crypto' commonName :PRINTABLE:'localhost' emailAddress :IA5STRING:'admin@server.example.dom' Certificate is to be certified until Mar 31 02:57:30 2002 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated Signed certificate is in newcert.pem ``` -------------------------------- ### Generate Recipient Certificate Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Generates a self-signed X.509 certificate for a recipient. This command also creates a 1024-bit RSA key pair, overwriting `privkey.pem` if it exists. The certificate is saved as `recipient.pem`. ```default openssl req -newkey rsa:1024 -nodes -x509 -days 365 -out recipient.pem Using configuration from /usr/local/pkg/openssl/openssl.cnf Generating a 1024 bit RSA private key .....................................++++++ .................++++++ writing new private key to 'privkey.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. ``` -------------------------------- ### Set PYTHONPATH for Individual Test Execution Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/AGENTS.md Before running individual tests, set the PYTHONPATH environment variable to the local build directory. This ensures that Python can locate the necessary M2Crypto modules. ```bash # Set up the environment (or look up BUILD_LIB_DIR from make output) export PYTHONPATH="$(find build -maxdepth 1 -type d -name \"lib.*\" | head -n 1)" ``` -------------------------------- ### Encrypt Message with S/MIME Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Encrypts a message using S/MIME with a specified cipher and recipient certificate. Seeds the PRNG and saves its state. ```python from M2Crypto import BIO, Rand, SMIME, X509 def makebuf(text): return BIO.MemoryBuffer(text) # Make a MemoryBuffer of the message. buf = makebuf(b'a sign of our times') # Seed the PRNG. Rand.load_file('randpool.dat', -1) # Instantiate an SMIME object. s = SMIME.SMIME() # Load target cert to encrypt to. x509 = X509.load_cert('recipient.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Set cipher: 3-key triple-DES in CBC mode. s.set_cipher(SMIME.Cipher('des_ede3_cbc')) # Encrypt the buffer. p7 = s.encrypt(buf) # Output p7 in mail-friendly format. out = BIO.MemoryBuffer() out.write(b'From: sender@example.dom\n') out.write(b'To: recipient@example.dom\n') out.write(b'Subject: M2Crypto S/MIME testing\n') s.write(out, p7) print(out.read().decode()) # Save the PRNG's state. Rand.save_file('randpool.dat') ``` -------------------------------- ### Decrypt and Verify S/MIME Message Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Decrypts an S/MIME message and prepares for verification. Requires the recipient's private key and certificate, and the signer's certificate. ```python from M2Crypto import BIO, SMIME, X509 # Instantiate an SMIME object. s = SMIME.SMIME() # Load private key and cert. s.load_key('recipient_key.pem', 'recipient.pem') # Load the signed/encrypted data. p7, data = SMIME.smime_load_pkcs7('se.p7') # After the above step, 'data' == None. # Decrypt p7. 'out' now contains a PKCS #7 signed blob. out = s.decrypt(p7) # Load the signer's cert. x509 = X509.load_cert('signer.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Load the signer's CA cert. In this case, because the signer's # cert is self-signed, it is the signer's cert itself. st = X509.X509_Store() st.load_info('signer.pem') s.set_x509_store(st) # Recall 'out' contains a PKCS #7 blob. ``` -------------------------------- ### Send S/MIME Messages via SMTP Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md A Python function to generate and send S/MIME-signed/encrypted messages via SMTP. It supports plain, signed, encrypted, and signed/encrypted messages based on provided keys and certificates. ```python from M2Crypto import BIO, SMIME, X509 import smtplib, string, sys def sendsmime(from_addr, to_addrs, subject, msg, from_key, from_cert=None, to_certs=None, smtpd='localhost'): msg_bio = BIO.MemoryBuffer(msg) sign = from_key encrypt = to_certs s = SMIME.SMIME() if sign: s.load_key(from_key, from_cert) if encrypt: p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT) else: p7 = s.sign(msg_bio, flags=SMIME.PKCS7_TEXT|SMIME.PKCS7_DETACHED) msg_bio = BIO.MemoryBuffer(msg) # Recreate coz sign() has consumed it. if encrypt: sk = X509.X509_Stack() for x in to_certs: sk.push(X509.load_cert(x)) s.set_x509_stack(sk) s.set_cipher(SMIME.Cipher('des_ede3_cbc')) tmp_bio = BIO.MemoryBuffer() if sign: s.write(tmp_bio, p7) else: tmp_bio.write(msg) p7 = s.encrypt(tmp_bio) out = BIO.MemoryBuffer() out.write(f'From: {from_addr}\r\n'.encode()) out.write(f'To: {", ".join(to_addrs)}\r\n'.encode()) out.write(f'Subject: {subject}\r\n'.encode()) if encrypt: s.write(out, p7) else: if sign: s.write(out, p7, msg_bio, SMIME.PKCS7_TEXT) else: out.write(b'\r\n') out.write(msg) out.close() with smtplib.SMTP(smtpd) as smtp: smtp.sendmail(from_addr, to_addrs, out.read()) ``` -------------------------------- ### Decrypt S/MIME Message from File Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Decrypts an S/MIME encrypted message loaded from a file. Requires loading the recipient's private key and certificate. ```python from M2Crypto import BIO, SMIME, X509 # Instantiate an SMIME object. s = SMIME.SMIME() # Load private key and cert. s.load_key('recipient_key.pem', 'recipient.pem') # Load the encrypted data. p7, data = SMIME.smime_load_pkcs7('encrypt.p7') # Decrypt p7. out = s.decrypt(p7) print(out) ``` -------------------------------- ### Encrypt S/MIME Message Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Encrypts a signed message using a specified cipher and recipient certificate. The output is formatted for email. ```python from M2Crypto import BIO, SMIME, X509, Rand # Assume 's' is an initialized SMIME object and 'p7' is the signed data. x509 = X509.load_cert('recipient.pem') sk = X509.X509_Stack() sk.push(x509) s.set_x509_stack(sk) # Set cipher: 3-key triple-DES in CBC mode. s.set_cipher(SMIME.Cipher('des_ede3_cbc')) # Create a temporary buffer. tmp = BIO.MemoryBuffer() # Write the signed message into the temporary buffer. s.write(tmp, p7) # Encrypt the temporary buffer. p7 = s.encrypt(tmp) # Output p7 in mail-friendly format. out = BIO.MemoryBuffer() out.write(b'From: sender@example.dom\n') out.write(b'To: recipient@example.dom\n') out.write(b'Subject: M2Crypto S/MIME testing\n') s.write(out, p7) print(out.read().decode()) # Save the PRNG's state. Rand.save_file('randpool.dat') ``` -------------------------------- ### Decrypt S/MIME Message from String Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.smime.md Decrypts an S/MIME encrypted message provided as a string. Loads the encrypted data into a BIO object. ```python from M2Crypto import SMIME, BIO # Instantiate an SMIME object. s = SMIME.SMIME() # Load private key and cert. s.load_key('private_key.pkcs7.pem', 'public_key.pkcs7.pem') # The Encrypted data data_raw = "MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAL3r2KUEnR+Ds7lunkNUAEYWqiyppvZipjoCobD1FFF+WdFoaHcxJ/p18EaHfgXVgQ9tIPmEVfbVnxB406rrVEN9dZIrHyHBszl8G5xGcwQpbiYmQgS9cJc7P9Ya/qSwc7fzKAi4eoUfr7BALl3qWI1X+R2KNShDaUoa21c0XehHu0Qb6d2hScEdTulpGhGUaTkwMN4ZJmA60enG7xhSW8RIyZLTx7glRaaI/hEP0LsfkfI+kpKNQ8u52s816/tih5hiVtvpipWOyBU+L3OHVbGy4uzb9vMGO22KDm7Dev9wYs2EzHQry/u33ygdHzZwYwAM5Dm1js3cnJ5vsJdME5zA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBC21FrAYYgygBf8j3Qxflb1gBASekTx2RHk+wRH3Gc0KA09" # Add relevant headers, newlines that separate header and data, and trailing newline. data = f"Content-Type: application/pkcs7-mime; name=\"smime.p7m\"\n\n{data_raw}\n".encode() # Load data into a BIO. bio = BIO.MemoryBuffer(data) # Load bio data into an SMIME object. p7, _data = SMIME.smime_load_pkcs7_bio(bio) # Decrypt p7. out = s.decrypt(p7) print(out) ``` -------------------------------- ### Patch CA.pl for 3-Year Validity Source: https://gitlab.com/m2crypto/m2crypto/-/blob/master/doc/howto.ca.md Apply this patch to CA.pl to set the default validity period for generated CA certificates to 1095 days (3 years). This ensures longer-lived CA certificates. ```diff --- CA.pl.org Sat Mar 31 12:40:13 2001 +++ CA.pl Sat Mar 31 12:41:15 2001 @@ -97,7 +97,7 @@ } else { print "Making CA certificate ...\n"; - system ("$REQ -new -x509 -keyout " \ - "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT $DAYS"); + system ("$REQ -new -x509 -keyout " \ + "${CATOP}/private/$CAKEY -out ${CATOP}/$CACERT -days 1095"); $RET=$?; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.