Skip to content

Instantly share code, notes, and snippets.

@enolfc
Created December 30, 2015 23:20
Show Gist options
  • Save enolfc/263b06b6abc8bb911a62 to your computer and use it in GitHub Desktop.
Save enolfc/263b06b6abc8bb911a62 to your computer and use it in GitHub Desktop.
voms + pyopenssl
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