1

I have created an HTTP server in python that executes some cryptographic algorithms. So I try to create vital variables for my cryptography outside the GET method, as I dont want them to change after each request.

Here is a sample of the code:

class Handler(BaseHTTPRequestHandler):


    def do_GET(self):       
        path = self.path
        print 'request for ' + path
        rootdir = '/Server'

        client_mac = path.split('?')[-1]            
        file_name = path.split('?')[0]

        if self.path.split('?')[0].endswith('.txt'):

            '''create client ID'''
            print 'Printing mac address of connected device ----> %s' % client_mac

            id1_secret_key = pre.keyGen(master_secret_key, client_mac)

            fr = open (rootdir + file_name)
            file_data = fr.read()
            sym_key_ciphertext = pre.encrypt(params, client_mac, sym_key);  
#more code follows

try:

    httpd = HTTPServer(('',8080), Handler)
    print 'Server is on and listening to port...7000'

    group = PairingGroup('SS512', secparam=1024)  
    pre = PreGA(group)
    (master_secret_key, params) = pre.setup()
    print params
    sym_key = OpenSSLRand().getRandomBytes(128) #128 bits
    sym_cipher = AuthenticatedCryptoAbstraction(sym_key)
    server_mac = get_mac()
    id2_secret_key = pre.keyGen(master_secret_key, str(server_mac))

    httpd.serve_forever() 
except KeyboardInterrupt:
    print '^C received,shutting down the web server'
    server.socket.close()

After the excution of a GET request i get the following Error:

File "server.py", line 157, in do_GET
ciphertext = pre.encrypt(params, client_mac, file_data);
UnboundLocalError: local variable 'params' referenced before assignment

I should mention that variable params has a value after the execution of pre.setup().Any advice would be helpful and deeply appreciated.

Amir
  • 10,600
  • 9
  • 48
  • 75
PL13
  • 393
  • 2
  • 5
  • 13

3 Answers3

2

If you get this error message you are trying to update a variable that is outside of your local scope.

You can either use a nonlocal statement or refactor your code.

A simpler example of something that would throw this error is:

x = 1
def update_one():
     x += 1
update_one()

You can always reference a variable in a parent frame but you can't modify it without using nonlocal or global.

Colin Schoen
  • 2,526
  • 1
  • 17
  • 26
  • That is irrelevant. You aren't updating the variable. You are mutating the object which is not changing the pointer at all. – Colin Schoen Jan 03 '16 at 17:58
  • I wouldn't consider mutating an object modifying a variable. I would consider it mutating or modifying the object. I suppose I could have been more clear. – Colin Schoen Jan 03 '16 at 18:03
2

You assign into params inside the function:

(master_secret_key, params) = pre.setup()

so it is a local variable. You access it before the assignment. It's unclear from your code where it happens, but the following line could do that, if it is inside the function:

sym_key_ciphertext = pre.encrypt(params, client_mac, sym_key)

so you get an error. Your code is not clear, but if it is a global variable, you should declare it as such:

global params
...
(master_secret_key, params) = pre.setup()

Better: don't use global variable, and assign a different one

Elazar
  • 20,415
  • 4
  • 46
  • 67
1

Either pass params into the do_GET method or assign it to a member field of BaseHTTPRequestHandler.

Alec
  • 583
  • 3
  • 21