summaryrefslogtreecommitdiff
path: root/OpenSSL/crypto/x509ext.c
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSSL/crypto/x509ext.c')
-rw-r--r--OpenSSL/crypto/x509ext.c83
1 files changed, 78 insertions, 5 deletions
diff --git a/OpenSSL/crypto/x509ext.c b/OpenSSL/crypto/x509ext.c
index f65fd0f..f8ecb4a 100644
--- a/OpenSSL/crypto/x509ext.c
+++ b/OpenSSL/crypto/x509ext.c
@@ -236,19 +236,92 @@ crypto_X509Extension_dealloc(crypto_X509ExtensionObj *self)
PyObject_Del(self);
}
+
+/* Special handling of subjectAltName. OpenSSL's builtin formatter,
+ * X509V3_EXT_print, mishandles NUL bytes allowing a truncated display that
+ * does not accurately reflect what's in the extension.
+ */
+int
+crypto_X509Extension_str_subjectAltName(crypto_X509ExtensionObj *self, BIO *bio) {
+ GENERAL_NAMES *names;
+ const X509V3_EXT_METHOD *method = NULL;
+ long i, length, num;
+ const unsigned char *p;
+
+ method = X509V3_EXT_get(self->x509_extension);
+ if (method == NULL) {
+ return -1;
+ }
+
+ p = self->x509_extension->value->data;
+ length = self->x509_extension->value->length;
+ if (method->it) {
+ names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
+ ASN1_ITEM_ptr(method->it)));
+ } else {
+ names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length));
+ }
+ if (names == NULL) {
+ return -1;
+ }
+
+ num = sk_GENERAL_NAME_num(names);
+ for (i = 0; i < num; i++) {
+ GENERAL_NAME *name;
+ ASN1_STRING *as;
+ name = sk_GENERAL_NAME_value(names, i);
+ switch (name->type) {
+ case GEN_EMAIL:
+ BIO_puts(bio, "email:");
+ as = name->d.rfc822Name;
+ BIO_write(bio, ASN1_STRING_data(as),
+ ASN1_STRING_length(as));
+ break;
+ case GEN_DNS:
+ BIO_puts(bio, "DNS:");
+ as = name->d.dNSName;
+ BIO_write(bio, ASN1_STRING_data(as),
+ ASN1_STRING_length(as));
+ break;
+ case GEN_URI:
+ BIO_puts(bio, "URI:");
+ as = name->d.uniformResourceIdentifier;
+ BIO_write(bio, ASN1_STRING_data(as),
+ ASN1_STRING_length(as));
+ break;
+ default:
+ /* use builtin print for GEN_OTHERNAME, GEN_X400,
+ * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
+ */
+ GENERAL_NAME_print(bio, name);
+ }
+ /* trailing ', ' except for last element */
+ if (i < (num - 1)) {
+ BIO_puts(bio, ", ");
+ }
+ }
+ sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
+
+ return 0;
+}
+
/*
* Print a nice text representation of the certificate request.
*/
static PyObject *
-crypto_X509Extension_str(crypto_X509ExtensionObj *self)
-{
+crypto_X509Extension_str(crypto_X509ExtensionObj *self) {
int str_len;
char *tmp_str;
PyObject *str;
BIO *bio = BIO_new(BIO_s_mem());
- if (!X509V3_EXT_print(bio, self->x509_extension, 0, 0))
- {
+ if (OBJ_obj2nid(self->x509_extension->object) == NID_subject_alt_name) {
+ if (crypto_X509Extension_str_subjectAltName(self, bio) == -1) {
+ BIO_free(bio);
+ exception_from_error_queue(crypto_Error);
+ return NULL;
+ }
+ } else if (!X509V3_EXT_print(bio, self->x509_extension, 0, 0)) {
BIO_free(bio);
exception_from_error_queue(crypto_Error);
return NULL;
@@ -267,7 +340,7 @@ PyTypeObject crypto_X509Extension_Type = {
"X509Extension",
sizeof(crypto_X509ExtensionObj),
0,
- (destructor)crypto_X509Extension_dealloc,
+ (destructor)crypto_X509Extension_dealloc,
NULL, /* print */
NULL, /* getattr */
NULL, /* setattr (setattrfunc)crypto_X509Name_setattr, */