Add function to return internal enoding of X509_NAME.
[openssl.git] / crypto / x509 / x_name.c
index e6a862e90d341989b5e7962b9be3bb22a08f8424..9133e3cb824c4420a9f6d08bd1c83eacd88a396b 100644 (file)
@@ -1,4 +1,3 @@
-/* crypto/asn1/x_name.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
 
 #include <stdio.h>
 #include <ctype.h>
 
 #include <stdio.h>
 #include <ctype.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
 #include "internal/x509_int.h"
 #include "internal/asn1_int.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
 #include "internal/x509_int.h"
 #include "internal/asn1_int.h"
-
-typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
-DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
+#include "x509_lcl.h"
 
 static int x509_name_ex_d2i(ASN1_VALUE **val,
                             const unsigned char **in, long len,
 
 static int x509_name_ex_d2i(ASN1_VALUE **val,
                             const unsigned char **in, long len,
@@ -102,11 +99,11 @@ IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
 
 ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
 
 ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
-ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
+static_ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
 
 ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
 
 ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
-ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
+static_ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
 
 /*
  * Normally that's where it would end: we'd have two nested STACK structures
 
 /*
  * Normally that's where it would end: we'd have two nested STACK structures
@@ -115,7 +112,7 @@ ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
  * convert to the external form.
  */
 
  * convert to the external form.
  */
 
-const ASN1_EXTERN_FUNCS x509_name_ff = {
+static const ASN1_EXTERN_FUNCS x509_name_ff = {
     NULL,
     x509_name_ex_new,
     x509_name_ex_free,
     NULL,
     x509_name_ex_new,
     x509_name_ex_free,
@@ -133,16 +130,14 @@ IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
 
 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
 {
 
 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
 {
-    X509_NAME *ret = NULL;
-    ret = OPENSSL_malloc(sizeof(X509_NAME));
-    if (!ret)
+    X509_NAME *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL)
         goto memerr;
     if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
         goto memerr;
     if ((ret->bytes = BUF_MEM_new()) == NULL)
         goto memerr;
         goto memerr;
     if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
         goto memerr;
     if ((ret->bytes = BUF_MEM_new()) == NULL)
         goto memerr;
-    ret->canon_enc = NULL;
-    ret->canon_enclen = 0;
     ret->modified = 1;
     *val = (ASN1_VALUE *)ret;
     return 1;
     ret->modified = 1;
     *val = (ASN1_VALUE *)ret;
     return 1;
@@ -150,8 +145,7 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
  memerr:
     ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
     if (ret) {
  memerr:
     ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
     if (ret) {
-        if (ret->entries)
-            sk_X509_NAME_ENTRY_free(ret->entries);
+        sk_X509_NAME_ENTRY_free(ret->entries);
         OPENSSL_free(ret);
     }
     return 0;
         OPENSSL_free(ret);
     }
     return 0;
@@ -160,14 +154,14 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
 static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
     X509_NAME *a;
 static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
     X509_NAME *a;
+
     if (!pval || !*pval)
         return;
     a = (X509_NAME *)*pval;
 
     BUF_MEM_free(a->bytes);
     sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
     if (!pval || !*pval)
         return;
     a = (X509_NAME *)*pval;
 
     BUF_MEM_free(a->bytes);
     sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
-    if (a->canon_enc)
-        OPENSSL_free(a->canon_enc);
+    OPENSSL_free(a->canon_enc);
     OPENSSL_free(a);
     *pval = NULL;
 }
     OPENSSL_free(a);
     *pval = NULL;
 }
@@ -232,8 +226,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
     *in = p;
     return ret;
  err:
     *in = p;
     return ret;
  err:
-    if (nm.x != NULL)
-        X509_NAME_free(nm.x);
+    X509_NAME_free(nm.x);
     ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     return 0;
 }
     ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     return 0;
 }
@@ -344,10 +337,8 @@ static int x509_name_canon(X509_NAME *a)
     X509_NAME_ENTRY *entry, *tmpentry = NULL;
     int i, set = -1, ret = 0;
 
     X509_NAME_ENTRY *entry, *tmpentry = NULL;
     int i, set = -1, ret = 0;
 
-    if (a->canon_enc) {
-        OPENSSL_free(a->canon_enc);
-        a->canon_enc = NULL;
-    }
+    OPENSSL_free(a->canon_enc);
+    a->canon_enc = NULL;
     /* Special case: empty X509_NAME => null encoding */
     if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
         a->canon_enclen = 0;
     /* Special case: empty X509_NAME => null encoding */
     if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
         a->canon_enclen = 0;
@@ -367,7 +358,7 @@ static int x509_name_canon(X509_NAME *a)
             set = entry->set;
         }
         tmpentry = X509_NAME_ENTRY_new();
             set = entry->set;
         }
         tmpentry = X509_NAME_ENTRY_new();
-        if (!tmpentry)
+        if (tmpentry == NULL)
             goto err;
         tmpentry->object = OBJ_dup(entry->object);
         if (!asn1_string_canon(tmpentry->value, entry->value))
             goto err;
         tmpentry->object = OBJ_dup(entry->object);
         if (!asn1_string_canon(tmpentry->value, entry->value))
@@ -383,7 +374,7 @@ static int x509_name_canon(X509_NAME *a)
 
     p = OPENSSL_malloc(a->canon_enclen);
 
 
     p = OPENSSL_malloc(a->canon_enclen);
 
-    if (!p)
+    if (p == NULL)
         goto err;
 
     a->canon_enc = p;
         goto err;
 
     a->canon_enc = p;
@@ -394,11 +385,9 @@ static int x509_name_canon(X509_NAME *a)
 
  err:
 
 
  err:
 
-    if (tmpentry)
-        X509_NAME_ENTRY_free(tmpentry);
-    if (intname)
-        sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
-                                             local_sk_X509_NAME_ENTRY_pop_free);
+    X509_NAME_ENTRY_free(tmpentry);
+    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
+                                         local_sk_X509_NAME_ENTRY_pop_free);
     return ret;
 }
 
     return ret;
 }
 
@@ -522,3 +511,72 @@ int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
     }
     return (*xn != NULL);
 }
     }
     return (*xn != NULL);
 }
+
+int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
+{
+    char *s, *c, *b;
+    int l, i;
+
+    l = 80 - 2 - obase;
+
+    b = X509_NAME_oneline(name, NULL, 0);
+    if (!b)
+        return 0;
+    if (!*b) {
+        OPENSSL_free(b);
+        return 1;
+    }
+    s = b + 1;                  /* skip the first slash */
+
+    c = s;
+    for (;;) {
+#ifndef CHARSET_EBCDIC
+        if (((*s == '/') &&
+             ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') ||
+                                                 ((s[2] >= 'A')
+                                                  && (s[2] <= 'Z')
+                                                  && (s[3] == '='))
+              ))) || (*s == '\0'))
+#else
+        if (((*s == '/') &&
+             (isupper(s[1]) && ((s[2] == '=') ||
+                                (isupper(s[2]) && (s[3] == '='))
+              ))) || (*s == '\0'))
+#endif
+        {
+            i = s - c;
+            if (BIO_write(bp, c, i) != i)
+                goto err;
+            c = s + 1;          /* skip following slash */
+            if (*s != '\0') {
+                if (BIO_write(bp, ", ", 2) != 2)
+                    goto err;
+            }
+            l--;
+        }
+        if (*s == '\0')
+            break;
+        s++;
+        l--;
+    }
+
+    OPENSSL_free(b);
+    return 1;
+ err:
+    X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB);
+    OPENSSL_free(b);
+    return 0;
+}
+
+int X509_NAME_get0_der(const unsigned char **pder, size_t *pderlen,
+                       X509_NAME *nm)
+{
+    /* Make sure encoding is valid */
+    if (i2d_X509_NAME(nm, NULL) <= 0)
+        return 0;
+    if (pder != NULL)
+        *pder = (unsigned char *)nm->bytes->data;
+    if (pderlen != NULL)
+        *pderlen = nm->bytes->length;
+    return 1;
+}