Created
December 30, 2015 23:20
-
-
Save enolfc/263b06b6abc8bb911a62 to your computer and use it in GitHub Desktop.
voms + pyopenssl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from OpenSSL import crypto | |
os.environ["OPENSSL_ALLOW_PROXY_CERTS"] = "1" | |
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert) | |
store = crypto.X509Store() | |
chain = crypto.load_certificate(crypto.FILETYPE_PEM, chain) | |
store.add_cert(chain) | |
store_ctx = crypto.X509StoreContext(store, cert) | |
# this is where it gets ugly | |
# this could be also done with cryptography | |
from OpenSSL._util import lib as _lib | |
# the chain is only available after verification, but pyopenssl destroys | |
# objects release every time this is called, so manually enforcing the call | |
# of verify + get_chain, then it must be destroyed below | |
ret = _lib.X509_verify_cert(store_ctx._store_ctx) | |
xch = _lib.X509_STORE_CTX_get_chain(store_ctx._store_ctx) | |
# VOMS Stuff | |
from cffi import FFI | |
ffi = FFI() | |
lib = ffi.dlopen('libvomsapi.so.1') | |
ffi.cdef(''' | |
struct voms { | |
int siglen; | |
char *signature; | |
char *user; | |
char *userca; | |
char *server; | |
char *serverca; | |
char *voname; | |
char *uri; | |
char *date1; | |
char *date2; | |
int type; | |
struct data **std; | |
char *custom; | |
int datalen; | |
int version; | |
char **fqan; | |
char *serial; | |
/* changed these to void * */ | |
void *ac; | |
void *holder; | |
}; | |
struct vomsdata { | |
char *cdir; | |
char *vdir; | |
struct voms **data; | |
char *workvo; | |
char *extra_data; | |
int volen; | |
int extralen; | |
struct vomsdata *real; | |
}; | |
extern struct vomsdata *VOMS_Init(char *voms, char *cert); | |
extern void VOMS_Destroy(struct vomsdata *vd); | |
extern int VOMS_SetVerificationType(int type, struct vomsdata *vd, int *error); | |
/* use here void * for cert and chains */ | |
extern int VOMS_Retrieve(void *cert, void *chain, int how, | |
struct vomsdata *vd, int *error); | |
''') | |
vd = lib.VOMS_Init("/etc/grid-security/vomsdir", | |
"/etc/grid-security/certificates/") | |
error = ffi.new("int *") | |
res = lib.VOMS_Retrieve(cert._x509, xch, 0, vd, error) | |
# Done here, once the x509 stack has been used | |
store_ctx._cleanup() | |
print res | |
print error[0] | |
d = {} | |
for attr in ('user', 'userca', 'server', 'serverca', | |
'voname', 'uri', 'serial', | |
('not_before', 'date1'), ('not_after', 'date2')): | |
if isinstance(attr, basestring): | |
d[attr] = ffi.string(getattr(vd.data[0], attr)) | |
else: | |
d[attr[0]] = ffi.string(getattr(vd.data[0], attr[1])) | |
d['version'] = vd.data[0].version | |
d["fqans"] = [] | |
# for loop fails with: | |
# TypeError: cdata 'char * *' does not support iteration | |
#for fqan in vd.data[0].fqan: | |
i = 0 | |
while True: | |
fqan = vd.data[0].fqan[i] | |
if fqan == ffi.NULL: | |
break | |
d["fqans"].append(ffi.string(fqan)) | |
i += 1 | |
import pprint | |
pprint.pprint(d) | |
lib.VOMS_Destroy(vd) | |
ca = "/etc/grid-security/certificates/9dd23746.0" | |
with open(ca, "r") as f: | |
ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) | |
store.add_cert(ca) | |
store_ctx.verify_certificate() | |
print "Verification OK!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment