Introduce X509_add_cert[s] simplifying various additions to cert lists
[openssl.git] / crypto / x509 / x509_cmp.c
index 25f72e057e746a9deaf7ae89a7071340eb87de51..0e770de11d66ee126650e0f84be0b7c37e37bd1e 100644 (file)
@@ -163,6 +163,62 @@ int X509_cmp(const X509 *a, const X509 *b)
     return rv;
 }
 
+int X509_add_cert_new(STACK_OF(X509) **sk, X509 *cert, int flags)
+{
+    if (*sk == NULL
+            && (*sk = sk_X509_new_null()) == NULL) {
+        X509err(0, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return X509_add_cert(*sk, cert, flags);
+}
+
+int X509_add_cert(STACK_OF(X509) *sk, X509 *cert, int flags)
+{
+    if (sk == NULL) {
+        X509err(0, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if ((flags & X509_ADD_FLAG_NO_DUP) != 0) {
+        /*
+         * not using sk_X509_set_cmp_func() and sk_X509_find()
+         * because this re-orders the certs on the stack
+         */
+        int i;
+
+        for (i = 0; i < sk_X509_num(sk); i++) {
+            if (X509_cmp(sk_X509_value(sk, i), cert) == 0)
+                return 1;
+        }
+    }
+    if ((flags & X509_ADD_FLAG_NO_SS) != 0 && X509_self_signed(cert, 0))
+        return 1;
+    if (!sk_X509_insert(sk, cert,
+                        (flags & X509_ADD_FLAG_PREPEND) != 0 ? 0 : -1)) {
+        X509err(0, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if ((flags & X509_ADD_FLAG_UP_REF) != 0)
+        (void)X509_up_ref(cert);
+    return 1;
+}
+
+int X509_add_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, int flags)
+/* compiler would allow 'const' for the list of certs, yet they are up-ref'ed */
+{
+    int n = sk_X509_num(certs); /* certs may be NULL */
+    int i;
+    for (i = 0; i < n; i++) {
+        int j = (flags & X509_ADD_FLAG_PREPEND) == 0 ? i : n - 1 - i;
+        /* if prepend, add certs in reverse order to keep original order */
+
+        if (!X509_add_cert(sk, sk_X509_value(certs, j), flags))
+            return 0;
+    }
+    return 1;
+}
+
 int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
 {
     int ret;