Secure XMLRPC Server / PEM Files

L

Laszlo Nagy

Daniel Crespo írta:
Hello everybody,

I'm trying to implement a secure xmlrpc server with basis on
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496786 recipe.
The thing that I'm concerned about is how can I get/create rapidly the
.pem files (the key and cert).

Any help?
Hello,

If you have OpenSSL installed, you can do the following:

1. Create a new directory and place the two attached files in it
(openssl.cnf and generate.sh)
2. Run "chmod +x gen_cert.sh ; ./gen_cert.sh yourdomain.com"
3. Answer to the questions. Be sure that your common name is your domain
name.

Then you will find PEM and DER formatted files. You should use the
unencrypted key.pem and cert.pem files.

Let me know if you have any problem.

Best,

Laszlo


#
# SSLeay example configuration file.
# This is mostly being used for generation of certificate requests.
#

RANDFILE = .rnd

####################################################################
[ ca ]
default_ca = CA_default # The default ca section

####################################################################
[ CA_default ]

dir = demoCA # Where everything is kept
certs = $dir\certs # Where the issued certs are kept
crl_dir = $dir\crl # Where the issued crl are kept
database = $dir\index.txt # database index file.
new_certs_dir = $dir\newcerts # default place for new certs.

certificate = $dir\cacert.pem # The CA certificate
serial = $dir\serial # The current serial number
crl = $dir\crl.pem # The current CRL
private_key = $dir\private\cakey.pem # The private key
RANDFILE = $dir\private\private.rnd # private random number file

x509_extensions = x509v3_extensions # The extentions to add to the cert
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :)
policy = policy_match

# For the CA policy
[ policy_match ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

####################################################################
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)

localityName = Locality Name (eg, city)

0.organizationName = Organization Name (eg, company)

organizationalUnitName = Organizational Unit Name (eg, section)

commonName = Common Name (eg, your website's domain name)
commonName_max = 64

emailAddress = Email Address
emailAddress_max = 40

[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20

[ x509v3_extensions ]

# under ASN.1, the 0 bit would be encoded as 80
nsCertType = 0x40

#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
#nsCertSequence
#nsCertExt
#nsDataType


openssl req -config openssl.cnf -new -out my-server.csr
openssl rsa -in privkey.pem -out my-server.key
openssl x509 -in my-server.csr -out my-server.cert -req -signkey my-server.key -days 1500
openssl x509 -in my-server.cert -out my-server.der.crt -outform DER

mv my-server.csr $1.csr
mv my-server.cert $1.cert.pem
mv my-server.key $1.key.pem
mv my-server.der.crt $1.der.crt

rm privkey.pem
rm -f .rnd
 
L

Laszlo Nagy

If you have OpenSSL installed, you can do the following:

1. Create a new directory and place the two attached files in it
(openssl.cnf and generate.sh)
2. Run "chmod +x gen_cert.sh ; ./gen_cert.sh yourdomain.com"
I meant generate.sh instead of gen_cert.sh.

Under windows it won't work. But you can easily convert generate.sh into
generate.bat. :)

Laszlo
 
D

Daniel Crespo

Laszlo said:
I meant generate.sh instead of gen_cert.sh.

Under windows it won't work. But you can easily convert generate.sh into
generate.bat. :)

Laszlo

I'm on Windows...
I'm also trying to get OpenSSL installed, but I need compilers and all
that stuff. Before getting involved in that, do you know of a faster
way to have it installed?

Thanks

Daniel
 
L

Laszlo Nagy

Daniel Crespo írta:
I'm on Windows...
I'm also trying to get OpenSSL installed, but I need compilers and all
that stuff. Before getting involved in that, do you know of a faster
way to have it installed?
Yes. Read the recipe once more. Especially, the first document string in
that program. ;-)

"""For windows users: http://webcleaner.sourceforge.net/pyOpenSSL-0.6.win32-py2.4.exe"""

(You will also need the openssl binaries for windows, but they are very easy to find.)


Laszlo
 
D

Daniel Crespo

Hi Laszlo,

I have read that. It's the wrapper for the usage of OpenSSL, so I have
to install it. I have downloaded the Borland C++ compiler, and I'm
doing so right now, but I'm not getting good results yet.

I tried to import OpenSSL, it seems to work.

Now, I want to try the code I submited earlier, but I need the .pem
files. You told me to change generate.sh to generate.bat. How can I do
that?

Many thanks,

Daniel
 
L

Laszlo Nagy

Daniel Crespo írta:
Hi Laszlo,

I have read that. It's the wrapper for the usage of OpenSSL, so I have
to install it. I have downloaded the Borland C++ compiler, and I'm
doing so right now, but I'm not getting good results yet.
You do not need any compiler. You just need to install the openssl
binaries and the wrapper.
I tried to import OpenSSL, it seems to work.
Great.
Now, I want to try the code I submited earlier, but I need the .pem
files. You told me to change generate.sh to generate.bat. How can I do
that?

Basically, use "del" instead of "rm" and use "move" instead of "mv". Use
<yourdomain.com> instead of $1. Moreover, openssl.exe must be on your
path. That's all.

Try this (untested):

openssl req -config openssl.cnf -new -out my-server.csr
openssl rsa -in privkey.pem -out my-server.key
openssl x509 -in my-server.csr -out my-server.cert -req -signkey my-server.key -days 1500
openssl x509 -in my-server.cert -out my-server.der.crt -outform DER

move my-server.csr yourdomain.com.csr
move my-server.cert yourdomain.com.cert.pem
move my-server.key yourdomain.com.key.pem
move my-server.der.crt yourdomain.com.der.crt

del privkey.pem


Laszlo
 
D

Daniel Crespo

Hi Laszlo,
Try this (untested):

openssl req -config openssl.cnf -new -out my-server.csr
openssl rsa -in privkey.pem -out my-server.key

Here's what I tried:

C:\OpenSSL\bin>openssl req -config openssl.cnf -new -out my-server.csr
Loading 'screen' into random state - done
Generating a 1024 bit RSA private key
..............++++++
...........................................++++++
writing new private key to 'privkey.pem'
Enter PEM pass phrase: PASSWORD
Verifying - Enter PEM pass phrase: PASSWORD
-----
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]:CN
State or Province Name (full name) [Some-State]:DF
Locality Name (eg, city) []:CITY
Organization Name (eg, company) [Internet Widgits Pty Ltd]:COMPANY
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:pASSWORD
An optional company name []:COMPANY

C:\OpenSSL\bin>openssl rsa -in privkey.pem -out my-server.key
Enter pass phrase for privkey.pem: PASSWORD
unable to load Private Key
3688:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad
decrypt:.\
crypto\evp\evp_enc.c:461:
3688:error:0906A065:pEM routines:pEM_do_header:bad
decrypt:.\crypto\pem\pem_lib.
c:425:

Any help?

Thanks in advance

Daniel
 
D

Daniel Crespo

Hi everybody,

For those who want to implement a SecureXMLRPCServer (HTTPS), here is
what I finally found in the Internet. I will summarise everything for
the people like me that need extra help just to get running an HTTPS
XMLRPC Server :)

This summary is not intended to be exhaustive, but just to give the
minimum steps to get running our server.

Here's the code (taken from
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496786):

"""SecureXMLRPCServer.py - simple XML RPC server supporting SSL.

Based on this article:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81549

For windows users:
http://webcleaner.sourceforge.net/pyOpenSSL-0.6.win32-py2.4.exe
"""

# Configure below
LISTEN_HOST='127.0.0.1' # You should not use '' here, unless you have a
real FQDN.
LISTEN_PORT=443

KEYFILE='your.key.pem' # Replace with your PEM formatted key file
CERTFILE=your.cert.pem' # Replace with your PEM formatted certificate
file
# Configure above

import SocketServer
import BaseHTTPServer
import SimpleHTTPServer
import SimpleXMLRPCServer

import socket, os
from OpenSSL import SSL

class
SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
def __init__(self, server_address, HandlerClass, logRequests=True):
"""Secure XML-RPC server.

It it very similar to SimpleXMLRPCServer but it uses HTTPS for
transporting XML data.
"""
self.logRequests = logRequests

SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self)
SocketServer.BaseServer.__init__(self, server_address,
HandlerClass)
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_privatekey_file (KEYFILE)
ctx.use_certificate_file(CERTFILE)
self.socket = SSL.Connection(ctx,
socket.socket(self.address_family,

self.socket_type))
self.server_bind()
self.server_activate()

class
SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
"""Secure XML-RPC request handler class.

It it very similar to SimpleXMLRPCRequestHandler but it uses HTTPS
for transporting XML data.
"""
def setup(self):
self.connection = self.request
self.rfile = socket._fileobject(self.request, "rb",
self.rbufsize)
self.wfile = socket._fileobject(self.request, "wb",
self.wbufsize)

def do_POST(self):
"""Handles the HTTPS POST request.

It was copied out from SimpleXMLRPCServer.py and modified to
shutdown the socket cleanly.
"""

try:
# get arguments
data = self.rfile.read(int(self.headers["content-length"]))
# In previous versions of SimpleXMLRPCServer, _dispatch
# could be overridden in this class, instead of in
# SimpleXMLRPCDispatcher. To maintain backwards
compatibility,
# check to see if a subclass implements _dispatch and
dispatch
# using that method if present.
response = self.server._marshaled_dispatch(
data, getattr(self, '_dispatch', None)
)
except: # This should only happen if the module is buggy
# internal error, report as HTTP server error
self.send_response(500)
self.end_headers()
else:
# got a valid XML RPC response
self.send_response(200)
self.send_header("Content-type", "text/xml")
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)

# shut down the connection
self.wfile.flush()
self.connection.shutdown() # Modified here!

def test(HandlerClass = SecureXMLRpcRequestHandler,ServerClass =
SecureXMLRPCServer):
"""Test xml rpc over https server"""
class xmlrpc_registers:
def __init__(self):
import string
self.python_string = string

def add(self, x, y):
return x + y

def mult(self,x,y):
return x*y

def div(self,x,y):
return x//y

server_address = (LISTEN_HOST, LISTEN_PORT) # (address, port)
server = ServerClass(server_address, HandlerClass)
server.register_instance(xmlrpc_registers())
sa = server.socket.getsockname()
print "Serving HTTPS on", sa[0], "port", sa[1]
server.serve_forever()


if __name__ == '__main__':
test()


# Here is the client for testing:
import xmlrpclib

server = xmlrpclib.Server('https://localhost:443')
print server.add(1,2)
print server.div(10,4)

------------------------------------------------------------

Now, here are the steps to get running it:

1. Install OpenSSL from www.openssl.org. If you are using Windows, go
to http://www.slproweb.com/products/Win32OpenSSL.html and install the
binary.

2. In order to have our required .pem files, put the following in a
batch file (.sh or .bat) and run it from the directory where openssl is
(unless it is set as an environment variable):

openssl req -config openssl.cnf -new -out my-server.csr
openssl rsa -in privkey.pem -out my-server.key
openssl x509 -in my-server.csr -out my-server.cert -req -signkey
my-server.key -days 1500
openssl x509 -in my-server.cert -out my-server.der.crt -outform DER

mv my-server.csr $1.csr
mv my-server.cert $1.cert.pem
mv my-server.key $1.key.pem
mv my-server.der.crt $1.der.crt

rm privkey.pem
rm -f .rnd

(for .bat, just ignore the last line and use "move" instead of "mv",
"del" instead of "rm" and "yourdomain.com" instead of "$1")

It will generate 4 files. Take the two with .pem extension, and put it
on the same directory as the SecureXMLRPCServer code.

3. In order for get running the code, install pyOpenSSL available at
http://pyopenssl.sourceforge.net/. For Windows you may prefer
http://webcleaner.sourceforge.net/pyOpenSSL-0.6.win32-py2.4.exe

That's it.

Special thanks to Laszlo Nagy

Enjoy!

Daniel Crespo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top