Remove a remaining file used with csrgen

This file was missed in the first pass to remove support for
csrgen.

This was never feature complete and currently has issues and
we lack the resources to maintain it.

Drop it for now. It can be revived from git history in the
future if we see the need.

https://pagure.io/freeipa/issue/8669

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Francois Cami <fcami@redhat.com>
This commit is contained in:
Rob Crittenden 2021-02-18 08:19:51 -05:00 committed by Florence Blanc-Renaud
parent dea2b8af9c
commit ab13cf52f2

View File

@ -1,387 +0,0 @@
from cffi import FFI
import ctypes.util
from ipalib import errors
_ffi = FFI()
_ffi.cdef('''
/* libcrypto/crypto.h */
unsigned long OpenSSL_version_num(void);
unsigned long SSLeay(void);
const char * OpenSSL_version(int t);
const char * SSLeay_version(int t);
#define OPENSSL_VERSION 0
''')
_libcrypto = _ffi.dlopen(ctypes.util.find_library('crypto'))
# SSLeay_version has been renamed with OpenSSL_version in OpenSSL 1.1.0
# LibreSSL has OpenSSL_version since 2.7.0
try:
OpenSSL_version = _libcrypto.OpenSSL_version
except AttributeError:
OpenSSL_version = _libcrypto.SSLeay_version
_version = OpenSSL_version(_libcrypto.OPENSSL_VERSION)
_version = _ffi.string(_version).decode('utf-8')
LIBRESSL = _version.startswith('LibreSSL')
if not _version.startswith("OpenSSL") and not LIBRESSL:
raise ImportError("Only LibreSSL and OpenSSL are supported")
# SSLeay has been renamed with OpenSSL_version_num in OpenSSL 1.1.0
# LibreSSL has OpenSSL_version_num since 2.7.0
try:
OpenSSL_version_num = _libcrypto.OpenSSL_version_num
except AttributeError:
OpenSSL_version_num = _libcrypto.SSLeay
# OpenSSL_version_num()/SSLeay() returns the value of OPENSSL_VERSION_NUMBER
#
# OPENSSL_VERSION_NUMBER is a numeric release version identifier:
# MNNFFPPS: major minor fix patch status
# For example,
# 0x000906000 == 0.9.6 dev
# 0x000906023 == 0.9.6b beta 3
# 0x00090605f == 0.9.6e release
_openssl_version = OpenSSL_version_num()
_ffi.cdef('''
typedef ... CONF;
typedef ... CONF_METHOD;
typedef ... BIO;
typedef ... ipa_STACK_OF_CONF_VALUE;
/* openssl/conf.h */
typedef struct {
char *section;
char *name;
char *value;
} CONF_VALUE;
CONF *NCONF_new(CONF_METHOD *meth);
void NCONF_free(CONF *conf);
int NCONF_load_bio(CONF *conf, BIO *bp, long *eline);
ipa_STACK_OF_CONF_VALUE *NCONF_get_section(const CONF *conf,
const char *section);
char *NCONF_get_string(const CONF *conf, const char *group, const char *name);
/* openssl/safestack.h */
// int sk_CONF_VALUE_num(ipa_STACK_OF_CONF_VALUE *);
// CONF_VALUE *sk_CONF_VALUE_value(ipa_STACK_OF_CONF_VALUE *, int);
/* openssl/stack.h */
typedef ... _STACK;
int OPENSSL_sk_num(const _STACK *);
void *OPENSSL_sk_value(const _STACK *, int);
int sk_num(const _STACK *);
void *sk_value(const _STACK *, int);
/* openssl/bio.h */
BIO *BIO_new_mem_buf(const void *buf, int len);
int BIO_free(BIO *a);
/* openssl/asn1.h */
typedef struct ASN1_ENCODING_st {
unsigned char *enc; /* DER encoding */
long len; /* Length of encoding */
int modified; /* set to 1 if 'enc' is invalid */
} ASN1_ENCODING;
/* openssl/evp.h */
typedef ... EVP_PKEY;
void EVP_PKEY_free(EVP_PKEY *pkey);
/* openssl/x509.h */
typedef ... ASN1_INTEGER;
typedef ... ASN1_BIT_STRING;
typedef ... ASN1_OBJECT;
typedef ... X509;
typedef ... X509_CRL;
typedef ... X509_NAME;
typedef ... X509_PUBKEY;
typedef ... ipa_STACK_OF_X509_ATTRIBUTE;
typedef struct X509_req_info_st {
ASN1_ENCODING enc;
ASN1_INTEGER *version;
X509_NAME *subject;
X509_PUBKEY *pubkey;
/* d=2 hl=2 l= 0 cons: cont: 00 */
ipa_STACK_OF_X509_ATTRIBUTE *attributes; /* [ 0 ] */
} X509_REQ_INFO;
''')
# since OpenSSL 1.1.0 req_info field is no longer pointer to X509_REQ_INFO
if _openssl_version >= 0x10100000 and not LIBRESSL:
_ffi.cdef('''
typedef struct X509_req_st {
X509_REQ_INFO req_info;
} X509_REQ;
''')
else:
_ffi.cdef('''
typedef struct X509_req_st {
X509_REQ_INFO *req_info;
} X509_REQ;
''')
_ffi.cdef('''
X509_REQ *X509_REQ_new(void);
void X509_REQ_free(X509_REQ *);
EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type,
const unsigned char *bytes, int len, int loc,
int set);
int X509_NAME_entry_count(X509_NAME *name);
int i2d_X509_REQ_INFO(X509_REQ_INFO *a, unsigned char **out);
/* openssl/objects.h */
ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name);
/* openssl/x509v3.h */
typedef ... X509V3_CONF_METHOD;
typedef struct v3_ext_ctx {
int flags;
X509 *issuer_cert;
X509 *subject_cert;
X509_REQ *subject_req;
X509_CRL *crl;
X509V3_CONF_METHOD *db_meth;
void *db;
} X509V3_CTX;
void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
X509_REQ *req, X509_CRL *crl, int flags);
void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
X509_REQ *req);
/* openssl/x509v3.h */
unsigned long ERR_get_error(void);
char *ERR_error_string(unsigned long e, char *buf);
''') # noqa: E501
NULL = _ffi.NULL
# openssl/conf.h
NCONF_new = _libcrypto.NCONF_new
NCONF_free = _libcrypto.NCONF_free
NCONF_load_bio = _libcrypto.NCONF_load_bio
NCONF_get_section = _libcrypto.NCONF_get_section
NCONF_get_string = _libcrypto.NCONF_get_string
# openssl/stack.h
try:
sk_num = _libcrypto.OPENSSL_sk_num
sk_value = _libcrypto.OPENSSL_sk_value
except AttributeError:
sk_num = _libcrypto.sk_num
sk_value = _libcrypto.sk_value
def sk_CONF_VALUE_num(sk):
return sk_num(_ffi.cast("_STACK *", sk))
def sk_CONF_VALUE_value(sk, i):
return _ffi.cast("CONF_VALUE *", sk_value(_ffi.cast("_STACK *", sk), i))
# openssl/bio.h
BIO_new_mem_buf = _libcrypto.BIO_new_mem_buf
BIO_free = _libcrypto.BIO_free
# openssl/x509.h
X509_REQ_new = _libcrypto.X509_REQ_new
X509_REQ_free = _libcrypto.X509_REQ_free
X509_REQ_set_pubkey = _libcrypto.X509_REQ_set_pubkey
d2i_PUBKEY_bio = _libcrypto.d2i_PUBKEY_bio
i2d_X509_REQ_INFO = _libcrypto.i2d_X509_REQ_INFO
X509_NAME_add_entry_by_OBJ = _libcrypto.X509_NAME_add_entry_by_OBJ
X509_NAME_entry_count = _libcrypto.X509_NAME_entry_count
def X509_REQ_get_subject_name(req):
return req.req_info.subject
# openssl/objects.h
OBJ_txt2obj = _libcrypto.OBJ_txt2obj
# openssl/evp.h
EVP_PKEY_free = _libcrypto.EVP_PKEY_free
# openssl/asn1.h
MBSTRING_UTF8 = 0x1000
# openssl/x509v3.h
X509V3_set_ctx = _libcrypto.X509V3_set_ctx
X509V3_set_nconf = _libcrypto.X509V3_set_nconf
X509V3_EXT_REQ_add_nconf = _libcrypto.X509V3_EXT_REQ_add_nconf
# openssl/err.h
ERR_get_error = _libcrypto.ERR_get_error
ERR_error_string = _libcrypto.ERR_error_string
def _raise_openssl_errors():
msgs = []
code = ERR_get_error()
while code != 0:
msg = _ffi.string(ERR_error_string(code, NULL))
try:
strmsg = msg.decode('utf-8')
except UnicodeDecodeError:
strmsg = repr(msg)
msgs.append(strmsg)
code = ERR_get_error()
raise errors.CSRTemplateError(reason='\n'.join(msgs))
def _parse_dn_section(subj, dn_sk):
for i in range(sk_CONF_VALUE_num(dn_sk)):
v = sk_CONF_VALUE_value(dn_sk, i)
rdn_type = _ffi.string(v.name)
# Skip past any leading X. X: X, etc to allow for multiple instances
for idx, c in enumerate(rdn_type):
if c in b':,.':
if idx+1 < len(rdn_type):
rdn_type = rdn_type[idx+1:]
break
if rdn_type.startswith(b'+'):
rdn_type = rdn_type[1:]
mval = -1
else:
mval = 0
# convert rdn_type to an OID
#
# OpenSSL is fussy about the case of the string. For example,
# lower-case 'o' (for "organization name") is not recognised.
# Therefore, try to convert the given string into an OID. If
# that fails, convert it upper case and try again.
#
oid = OBJ_txt2obj(rdn_type, 0)
if oid == NULL:
oid = OBJ_txt2obj(rdn_type.upper(), 0)
if oid == NULL:
raise errors.CSRTemplateError(
reason='unrecognised attribute type: {}'
.format(rdn_type.decode('utf-8')))
if not X509_NAME_add_entry_by_OBJ(
subj, oid, MBSTRING_UTF8,
_ffi.cast("unsigned char *", v.value), -1, -1, mval):
_raise_openssl_errors()
if not X509_NAME_entry_count(subj):
raise errors.CSRTemplateError(
reason='error, subject in config file is empty')
def build_requestinfo(config, public_key_info):
'''
Return a cffi buffer containing a DER-encoded CertificationRequestInfo.
The returned object implements the buffer protocol.
'''
reqdata = NULL
req = NULL
nconf_bio = NULL
pubkey_bio = NULL
pubkey = NULL
try:
reqdata = NCONF_new(NULL)
if reqdata == NULL:
_raise_openssl_errors()
nconf_bio = BIO_new_mem_buf(config, len(config))
errorline = _ffi.new('long[1]', [-1])
i = NCONF_load_bio(reqdata, nconf_bio, errorline)
if i < 0:
if errorline[0] < 0:
raise errors.CSRTemplateError(reason="Can't load config file")
else:
raise errors.CSRTemplateError(
reason='Error on line %d of config file' % errorline[0])
dn_sect = NCONF_get_string(reqdata, b'req', b'distinguished_name')
if dn_sect == NULL:
raise errors.CSRTemplateError(
reason='Unable to find "distinguished_name" key in config')
dn_sk = NCONF_get_section(reqdata, dn_sect)
if dn_sk == NULL:
raise errors.CSRTemplateError(
reason='Unable to find "%s" section in config' %
_ffi.string(dn_sect))
pubkey_bio = BIO_new_mem_buf(public_key_info, len(public_key_info))
pubkey = d2i_PUBKEY_bio(pubkey_bio, NULL)
if pubkey == NULL:
_raise_openssl_errors()
req = X509_REQ_new()
if req == NULL:
_raise_openssl_errors()
subject = X509_REQ_get_subject_name(req)
_parse_dn_section(subject, dn_sk)
if not X509_REQ_set_pubkey(req, pubkey):
_raise_openssl_errors()
ext_ctx = _ffi.new("X509V3_CTX[1]")
X509V3_set_ctx(ext_ctx, NULL, NULL, req, NULL, 0)
X509V3_set_nconf(ext_ctx, reqdata)
extn_section = NCONF_get_string(reqdata, b"req", b"req_extensions")
if extn_section != NULL:
if not X509V3_EXT_REQ_add_nconf(
reqdata, ext_ctx, extn_section, req):
_raise_openssl_errors()
if _openssl_version < 0x10100000 or LIBRESSL:
der_len = i2d_X509_REQ_INFO(req.req_info, NULL)
else:
req_info = _ffi.new("X509_REQ_INFO *", req.req_info)
der_len = i2d_X509_REQ_INFO(req_info, NULL)
req.req_info = req_info[0]
if der_len < 0:
_raise_openssl_errors()
der_buf = _ffi.new("unsigned char[%d]" % der_len)
der_out = _ffi.new("unsigned char **", der_buf)
if _openssl_version < 0x10100000 or LIBRESSL:
der_len = i2d_X509_REQ_INFO(req.req_info, der_out)
else:
der_len = i2d_X509_REQ_INFO(req_info, der_out)
req.req_info = req_info[0]
if der_len < 0:
_raise_openssl_errors()
return _ffi.buffer(der_buf, der_len)
finally:
if reqdata != NULL:
NCONF_free(reqdata)
if req != NULL:
X509_REQ_free(req)
if nconf_bio != NULL:
BIO_free(nconf_bio)
if pubkey_bio != NULL:
BIO_free(pubkey_bio)
if pubkey != NULL:
EVP_PKEY_free(pubkey)