Changeset 6835 for TI12-security/branches
- Timestamp:
- 21/04/10 15:04:59 (11 years ago)
- Location:
- TI12-security/branches/MyProxyClient-pyopenssl
- Files:
-
- 3 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TI12-security/branches/MyProxyClient-pyopenssl/myproxy/client.py
r6829 r6835 26 26 import os 27 27 import socket 28 from M2Crypto import X509, RSA, EVP, m2, BIO, SSL, util29 28 import base64 29 import traceback 30 from cStringIO import StringIO 30 31 from ConfigParser import SafeConfigParser 32 33 from OpenSSL import crypto, SSL 31 34 32 35 from myproxy.utils.openssl import OpenSSLConfig, OpenSSLConfigError … … 43 46 44 47 45 class _HostCheck(SSL.Checker.Checker):46 """Override SSL.Checker.Checker to allow additional check of MyProxy47 server identity. If hostname doesn't match, allow match of host's48 Distinguished Name against MYPROXY_SERVER_DN setting"""49 50 def __init__(self,51 myProxyServerDN=os.environ.get('MYPROXY_SERVER_DN'),52 cnHostPfx='host/',53 **kw):54 """Override parent class __init__ to enable setting of myProxyServerDN55 setting56 57 @type myProxyServerDN: string58 @param myProxyServerDN: Set the expected Distinguished Name of the59 MyProxy server to avoid errors matching hostnames. This is useful60 where the hostname is not fully qualified61 62 @type cnHostPfx: string63 @param cnHostPfx: globus host certificates are64 generated by default with a 'host/' prefix to the host name. Set65 this keyword to '' or None to override and omit the prefix"""66 67 SSL.Checker.Checker.__init__(self, **kw)68 69 self.myProxyServerDN = myProxyServerDN70 self.cnHostPfx = cnHostPfx71 72 73 def __call__(self, peerCert, host=None):74 """Carry out checks on server ID75 @type peerCert: basestring76 @param peerCert: MyProxy server host certificate as M2Crypto.X509.X50977 instance78 @type host: basestring79 @param host: name of host to check80 """81 82 # Globus host certificate has a "host/" prefix - see explanation in83 # __init__.__doc__84 cnHostPfx = isinstance(self.cnHostPfx, basestring) \85 and self.cnHostPfx or ''86 host = None or cnHostPfx + self.host87 88 try:89 SSL.Checker.Checker.__call__(self, peerCert, host=host)90 91 except SSL.Checker.WrongHost, e:92 # Try match against DN set from MYPROXY_SERVER_DN / config93 # file setting94 peerCertDN = '/'+peerCert.get_subject().as_text().replace(', ','/')95 96 # If they match drop the exception and return all OK instead97 if peerCertDN != self.myProxyServerDN:98 raise99 100 return True48 #class _HostCheck(SSL.Checker.Checker): 49 # """Override SSL.Checker.Checker to allow additional check of MyProxy 50 # server identity. If hostname doesn't match, allow match of host's 51 # Distinguished Name against MYPROXY_SERVER_DN setting""" 52 # 53 # def __init__(self, 54 # myProxyServerDN=os.environ.get('MYPROXY_SERVER_DN'), 55 # cnHostPfx='host/', 56 # **kw): 57 # """Override parent class __init__ to enable setting of myProxyServerDN 58 # setting 59 # 60 # @type myProxyServerDN: string 61 # @param myProxyServerDN: Set the expected Distinguished Name of the 62 # MyProxy server to avoid errors matching hostnames. This is useful 63 # where the hostname is not fully qualified 64 # 65 # @type cnHostPfx: string 66 # @param cnHostPfx: globus host certificates are 67 # generated by default with a 'host/' prefix to the host name. Set 68 # this keyword to '' or None to override and omit the prefix""" 69 # 70 # SSL.Checker.Checker.__init__(self, **kw) 71 # 72 # self.myProxyServerDN = myProxyServerDN 73 # self.cnHostPfx = cnHostPfx 74 # 75 # 76 # def __call__(self, peerCert, host=None): 77 # """Carry out checks on server ID 78 # @type peerCert: basestring 79 # @param peerCert: MyProxy server host certificate as M2Crypto.X509.X509 80 # instance 81 # @type host: basestring 82 # @param host: name of host to check 83 # """ 84 # 85 # # Globus host certificate has a "host/" prefix - see explanation in 86 # # __init__.__doc__ 87 # cnHostPfx = isinstance(self.cnHostPfx, basestring) \ 88 # and self.cnHostPfx or '' 89 # host = None or cnHostPfx + self.host 90 # 91 # try: 92 # SSL.Checker.Checker.__call__(self, peerCert, host=host) 93 # 94 # except SSL.Checker.WrongHost, e: 95 # # Try match against DN set from MYPROXY_SERVER_DN / config 96 # # file setting 97 # peerCertDN = '/'+peerCert.get_subject().as_text().replace(', ','/') 98 # 99 # # If they match drop the exception and return all OK instead 100 # if peerCertDN != self.myProxyServerDN: 101 # raise 102 # 103 # return True 101 104 102 105 … … 503 506 not needed in the case of a proxy private key 504 507 """ 505 506 508 # Must be version 3 for MyProxy 507 context = SSL.Context( protocol='sslv3')508 509 context = SSL.Context(SSL.SSLv3_METHOD) 510 509 511 if self.caCertFilePath or self.caCertDir: 510 context.load_verify_locations(cafile=self.caCertFilePath, 511 capath=self.caCertDir) 512 513 # Stop if peer's certificate can't be verified 514 context.set_allow_unknown_ca(False) 515 else: 516 context.set_allow_unknown_ca(True) 512 context.load_verify_locations(self.caCertFilePath, self.caCertDir) 517 513 518 514 if ownerCertFile: 519 515 try: 520 context.load_cert_chain(ownerCertFile, 521 keyfile=ownerKeyFile, 522 callback=lambda *ar, **kw: ownerPassphrase) 523 except Exception, e: 516 # context.use_certificate_file(ownerCertFile) 517 context.use_certificate_chain_file(ownerCertFile) 518 def pwdCallback(passphraseMaxLen, 519 promptPassphraseTwice, 520 passphrase): 521 if passphrase is None: 522 return True 523 else: 524 if len(passphrase) > passphraseMaxLen: 525 log.error('Passphrase length %d is greater than ' 526 'the maximum length allowed %d', 527 len(passphrase), passphraseMaxLen) 528 return '' 529 return passphrase 530 531 context.set_passwd_cb(pwdCallback, ownerPassphrase) 532 context.use_privatekey_file(ownerKeyFile) 533 except Exception: 524 534 raise MyProxyClientConfigError("Loading certificate " 525 535 "and private key for SSL " 526 536 "connection [also check CA " 527 "certificate settings]: %s" % e) 528 529 # Verify peer's certificate 530 context.set_verify(SSL.verify_peer, 1) 537 "certificate settings]: %s" % 538 traceback.format_exc()) 539 540 # Verify peer's certificate 541 def callback(connection, x509Cert, *arg, **kw): 542 return True 543 544 context.set_verify(SSL.VERIFY_PEER, callback) 531 545 532 546 … … 534 548 # globus doesn't handle this case, apparently, and instead 535 549 # chokes in proxy delegation code 536 context.set_options( m2.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)550 context.set_options(SSL.OP_DONT_INSERT_EMPTY_FRAGMENTS) 537 551 538 552 # connect to myproxy server 539 conn = SSL.Connection(context, sock =socket.socket())553 conn = SSL.Connection(context, socket.socket()) 540 554 541 555 # Check server host identity - if host doesn't match use explicit 542 556 # 'serverDN' 543 557 # host/<hostname> one 544 hostCheck = _HostCheck(host=self.hostname,545 myProxyServerDN=self.serverDN,546 cnHostPfx=self.serverCNPrefix)547 conn.set_post_connection_check_callback(hostCheck)558 # hostCheck = _HostCheck(host=self.hostname, 559 # myProxyServerDN=self.serverDN, 560 # cnHostPfx=self.serverCNPrefix) 561 # conn.set_post_connection_check_callback(hostCheck) 548 562 549 563 return conn 550 564 551 def _createKey s(self, nBitsForKey=PRIKEY_NBITS):565 def _createKeyPair(self, nBitsForKey=PRIKEY_NBITS): 552 566 """Generate key pair and return as PEM encoded string 553 567 @type nBitsForKey: int … … 557 571 @return: public/private key pair 558 572 """ 559 keyPair = RSA.gen_key(nBitsForKey, 65537L,#m2.RSA_F4,560 callback=lambda *arg, **kw: None)573 keyPair = crypto.PKey() 574 keyPair.generate_key(crypto.TYPE_RSA, nBitsForKey) 561 575 562 576 return keyPair … … 578 592 # Check all required certifcate request DN parameters are set 579 593 # Create certificate request 580 req = X509.Request()594 certReq = crypto.X509Req() 581 595 582 596 # Create public key object 583 pubKey = EVP.PKey() 584 pubKey.assign_rsa(keyPair) 597 certReq.set_pubkey(keyPair) 585 598 586 599 # Add the public key to the request 587 req.set_version(0) 588 req.set_pubkey(pubKey) 589 590 defaultReqDN = self._openSSLConfig.reqDN 591 592 # Set DN 593 x509Name = X509.X509_Name() 594 x509Name.CN = CN 595 596 if defaultReqDN: 597 x509Name.OU = defaultReqDN['OU'] 598 x509Name.O = defaultReqDN['O'] 599 600 req.set_subject_name(x509Name) 601 req.sign(pubKey, messageDigest) 602 603 return req.as_der() 600 certReq.sign(keyPair, messageDigest) 601 602 derCertReq = crypto.dump_certificate_request(crypto.FILETYPE_ASN1, 603 certReq) 604 605 return derCertReq 604 606 605 607 def _deserializeResponse(self, msg, *fieldNames): … … 648 650 649 651 @return list containing the equivalent to the input in PEM format""" 650 pemCerts = [] 652 pemCerts = [] 651 653 dat = inputDat 652 654 653 while dat: 655 while dat: 654 656 # find start of cert, get length 655 657 ind = dat.find('\x30\x82') … … 661 663 # extract der-format cert, and convert to pem 662 664 derCert = dat[ind:ind+len+4] 663 664 x509 = X509.load_cert_der_string(derCert) 665 pemCert = x509.as_pem() 666 665 x509Cert = crypto.load_certificate(crypto.FILETYPE_ASN1, derCert) 666 pemCert = crypto.dump_certificate(crypto.FILETYPE_PEM, x509Cert) 667 667 pemCerts.append(pemCert) 668 668 … … 1009 1009 1010 1010 # Send certificate and private key 1011 certTxt = X509.load_cert(certFile).as_pem()1011 certTxt = open(certFile).read() 1012 1012 keyTxt = open(keyFile).read() 1013 1013 … … 1051 1051 # If no key pair was passed, generate here 1052 1052 if keyPair is None: 1053 keyPair = self._createKey s(nBitsForKey=nBitsForKey)1053 keyPair = self._createKeyPair(nBitsForKey=nBitsForKey) 1054 1054 1055 1055 certReq = self._createCertReq(username, keyPair) 1056 1056 1057 1057 if keyPair is not None: 1058 pemKeyPair = keyPair.as_pem(cipher=None, 1059 callback=util.no_passphrase_callback) 1058 pemKeyPair = crypto.dump_privatekey(crypto.FILETYPE_PEM, keyPair) 1060 1059 1061 1060 # Set-up SSL connection … … 1147 1146 for tries in range(MyProxyClient.MAX_RECV_TRIES): 1148 1147 dat += conn.recv(MyProxyClient.SERVER_RESP_BLK_SIZE) 1149 except SSL.S SLError:1148 except SSL.SysCallError: 1150 1149 # Expect this exception when response content exhausted 1151 1150 pass -
TI12-security/branches/MyProxyClient-pyopenssl/myproxy/test/proxy.crt
r6829 r6835 1 1 -----BEGIN CERTIFICATE----- 2 MIICf DCCAeWgAwIBAgIEFEquwTANBgkqhkiG9w0BAQUFADAlMRAwDgYDVQQKEwdH3 YWJyaWVsMREwDwYDVQQDEwh0ZXN0dXNlcjAeFw0xMDA0MjE wOTI5MDNaFw0xMDA04 MjIw MzM0MDNaMDkxEDAOBgNVBAoTB0dhYnJpZWwxETAPBgNVBAMTCHRlc3R1c2Vy5 MR IwEAYDVQQDEwkzNDA0Mzg3MjEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK6 AoIBAQDySWTRVbS6L5T9UUoTpARD+Jk6H8NFp9Y1TjFWPaKySKa9ep0Gdj0vM83B 7 84Hz0U2R6FgdoaTBFIB2pbugjbm3pl8FIRZKaq7gdO6otmC21Y5XpjVA0s/fgyBG 8 y0iKqG78lSDnaBmVyaCra+2a7kkqsxGwUCMAlnxmZPqsHKXuRozRwTassH+BdUIt9 A3oUe7M1PQLo3e5hwJWg/7igRHc7kHItaSRUcXeZ7RNnY/DNSU6ww/ovWFZajqpt 10 cCyFpmRZ6nPx2jhxWyKvu8xi+NeKlkwc9mmqcWdJD1iRomQWNJAgG85Bm2oZSlMV 11 xJwMoiEZRxNk1yzBTMlqRW+Tcu69AgMBAAGjITAfMB0GCCsGAQUFBwEOAQH/BA4w 12 DDAKBggrBgEFBQcVATANBgkqhkiG9w0BAQUFAAOBgQDcbaaHn/fP61V97xl+24v/ 13 qFaFG4F415QD6o7ZTV0o1dub1ygXO5FaVBYgDa7bxV72qZw24rxbLs5fxVkKBAWc 14 HYidDjG9FlDcgEC43Y6NSyugvuoPowBx/IPdRe2e/ub0qbZrAm7Xz8mNJKfVXkV8 15 v hj9yMRFrxmIyqFVoSI+QA==2 MIICfTCCAeagAwIBAgIEVdVpFTANBgkqhkiG9w0BAQUFADAlMRAwDgYDVQQKEwdH 3 YWJyaWVsMREwDwYDVQQDEwh0ZXN0dXNlcjAeFw0xMDA0MjExMzU1MjFaFw0xMDA0 4 MjIwODAwMjFaMDoxEDAOBgNVBAoTB0dhYnJpZWwxETAPBgNVBAMTCHRlc3R1c2Vy 5 MRMwEQYDVQQDEwoxNDQwMDQ5NDI5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 6 CgKCAQEAt6SUcdngNsLJLGw28UfGRHGL9y0YQJ3D4c7L6JnV2KSWleqi3BZr95HV 7 O2BD2jFiH0aGShDqzdaB6SM4TVtxcW1XVrVhUNIIFrfGHo20qaWNQhV2zvosJXaI 8 J7w2nGwKtHdiARdMKQ0xQKPeS4Ww6HPcsTljFi0Yix4zmIZUcXLtW97VxTN8nJ2t 9 UvJD2Bu48i+z3pb1025ODReAr2XvxKoAVgBdwntc3/gjKVkrpX54lOLKeLQOOGxq 10 7GavctxfXiWQ7j4CiQZ/3AHiqimXbJnJWYU9v9tC2JQRrQ6gyepdUe2IDedavWfH 11 tBLhTDSm8d+s6BgF4BetYaq64R11hwIDAQABoyEwHzAdBggrBgEFBQcBDgEB/wQO 12 MAwwCgYIKwYBBQUHFQEwDQYJKoZIhvcNAQEFBQADgYEAI5I7ZIWMS0b53V0JaM4I 13 IbzWZnRW0LK/grerRJd3VVmiG4odMsooY0jKjSokxZTnXme+YxtD4wrBwQ4Z6BSr 14 D8/LTEwB/rkdEBlr23TSZnCZXBq0PuKKpSlcD3nT152/3QQ21VZaPJwgSsb0WadF 15 vdYgtEd43hsOTkIsH7KG4lA= 16 16 -----END CERTIFICATE----- 17 17 -----BEGIN CERTIFICATE----- -
TI12-security/branches/MyProxyClient-pyopenssl/myproxy/test/proxy.key
r6829 r6835 1 1 -----BEGIN RSA PRIVATE KEY----- 2 MAMCAQA= 2 MIIEpQIBAAKCAQEAt6SUcdngNsLJLGw28UfGRHGL9y0YQJ3D4c7L6JnV2KSWleqi 3 3BZr95HVO2BD2jFiH0aGShDqzdaB6SM4TVtxcW1XVrVhUNIIFrfGHo20qaWNQhV2 4 zvosJXaIJ7w2nGwKtHdiARdMKQ0xQKPeS4Ww6HPcsTljFi0Yix4zmIZUcXLtW97V 5 xTN8nJ2tUvJD2Bu48i+z3pb1025ODReAr2XvxKoAVgBdwntc3/gjKVkrpX54lOLK 6 eLQOOGxq7GavctxfXiWQ7j4CiQZ/3AHiqimXbJnJWYU9v9tC2JQRrQ6gyepdUe2I 7 DedavWfHtBLhTDSm8d+s6BgF4BetYaq64R11hwIDAQABAoIBAQCC3tarDAms/MNA 8 1R2SdQPmYsTMMWbHJacilKzb5kVvTlvCGqRVE+V9WIANAF1acTbr8uZggg3TArsx 9 2deVyUTfAHztXfUsE4GQLwcRXwsQmto/7evtNHuhdwcwygBhGN3IHgvJm0C7QJuI 10 5T7Vs0CPZ4IvCiaC90A2ZB+A4rnq3jbJqwXyw4vqqVGsP/5nggqT5F1/uqHe9pHW 11 +9GNXbj2HR4DCP8VyNzaSA3tJh5RFtpAx0Tby6FZ6+yC+dORZG51ApuUam/5EqVp 12 YS3SvGYWOyc6Cb3wKR5839K/ZXazN/V6swTbmnFMqerfgZ8OD1uFu2C7fmcHcz34 13 N5rWs36BAoGBAOMm9o4eALXFyon47jrJxjiTteRvHKKCXu5jMhnCp41+xV1M2a1L 14 qlVK44OnF+WoJPc8SAZGhGXagZKex2fXjpAYZZVZiyCuEjbAwpZpTI7aSH/Ygsj0 15 zeBck1Nl3jOf3DhXZa2PlPamBTc6A08bIG9foB09VqP4QGCXqQ8wbrFDAoGBAM73 16 EWn02YEJ7Qex+JNoUCPmPkDmAWBrUvypjuG+cP8mSY7zice2LlRNwKXh6jX9DuWi 17 cNB1GXwijvyHpUuUVOoOqu5jHVPZAq1IdwlQ21Gcv0dIb90aeJAk1kxFTWwQdC5Z 18 HR+cDnCBh57lVrRlnuhv1OGK1j3UDUtSs8ZyxlRtAoGBAMQAzOLYlLhEkX34ZGgp 19 z3bmTh9smQLJB+0ffw2nXzjC2L6nH3VfQv0R/7uMJRyvuCX1yBhSJNBWeVPw2hOK 20 dqNzycPTXi+2xFSmg8GR3tOtGr3mLwQD6NneR+nAjrlxCW88Sqo2qM0jeICs+En8 21 GELB+sEAOpCGF9bBRsmqevlNAoGBAJTsp7UsoM3/jHX7FDlN2EzcwnMEjn0I/UAd 22 6lh6JukSbd/VUpFIgHHdOQCkXVnX7D5E8xStDleKroT8Pm7yH2AEie7blyDciNaT 23 zEQB0K8bMXBjqUraX2KpfyKGw7084bzwFsrGCoXeTu6BbDCG5x+uSOq6cosu6RoI 24 OqBTum7JAoGAJiykiLWkcwu6zDYly4c31gk42Am9I5i/ZKuFdIZrX2Vrwex/QTRR 25 HGHqM2/7yyDDMeS6XRXEETA5zZzcTr3+s3oluLbD79dNUTh6PVh9mb2GF6fwJcgB 26 M+a7tIqlxWJMN5erHvp13imHMLIhqtTiSm18lUDBIzDAL70W6Kor8co= 3 27 -----END RSA PRIVATE KEY----- -
TI12-security/branches/MyProxyClient-pyopenssl/myproxy/test/test_myproxyclient.py
r6829 r6835 20 20 from os import path 21 21 22 from M2Crypto import X50922 from OpenSSL import crypto 23 23 24 24 from myproxy.client import CaseSensitiveConfigParser, MyProxyClient … … 102 102 print "proxy credentials:" 103 103 print ''.join(creds) 104 open(proxyCertFile, 'w').write(creds[0]+''.join(creds[2:])) 104 open(proxyCertFile, 'w').write(creds[0]+''.join(creds[2:])) 105 105 open(proxyKeyFile, 'w').write(creds[1]) 106 106 … … 117 117 118 118 credExists, errorTxt, fields = self.clnt.info( 119 120 121 122 119 thisSection['username'], 120 path.expandvars(thisSection['ownerCertFile']), 121 path.expandvars(thisSection['ownerKeyFile']), 122 ownerPassphrase=ownerPassphrase) 123 123 print "test3Info... " 124 124 print "credExists: %s" % credExists … … 182 182 if fileName.endswith('.0'): 183 183 # test parsing certificate 184 cert = X509.load_cert_string(fileContents, X509.FORMAT_PEM) 184 cert = crypto.load_certificate(crypto.FILETYPE_PEM, 185 fileContents) 185 186 self.assert_(cert) 186 self.assert_(isinstance(cert, X509.X509))187 self.assert_(isinstance(cert, crypto.X509)) 187 188 subj = cert.get_subject() 188 189 self.assert_(subj)
Note: See TracChangeset
for help on using the changeset viewer.