cert.c revision bf01e8179cbb2be476805340636098deda7e1366
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch/*
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch SSSD - certificate handling utils - openssl version
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch Copyright (C) Sumit Bose <sbose@redhat.com> 2015
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch This program is free software; you can redistribute it and/or modify
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch it under the terms of the GNU General Public License as published by
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch the Free Software Foundation; either version 3 of the License, or
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch (at your option) any later version.
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch This program is distributed in the hope that it will be useful,
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch but WITHOUT ANY WARRANTY; without even the implied warranty of
042a58438dc324c6d4de18e4c8a68044d6328e66Stephan Bosch MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
042a58438dc324c6d4de18e4c8a68044d6328e66Stephan Bosch GNU General Public License for more details.
042a58438dc324c6d4de18e4c8a68044d6328e66Stephan Bosch
042a58438dc324c6d4de18e4c8a68044d6328e66Stephan Bosch You should have received a copy of the GNU General Public License
042a58438dc324c6d4de18e4c8a68044d6328e66Stephan Bosch along with this program. If not, see <http://www.gnu.org/licenses/>.
042a58438dc324c6d4de18e4c8a68044d6328e66Stephan Bosch*/
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch#include <openssl/x509.h>
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch#include <openssl/bio.h>
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch#include <openssl/pem.h>
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch#include "util/util.h"
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Boscherrno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob,
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch size_t der_size, char **pem, size_t *pem_size)
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch{
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch X509 *x509 = NULL;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch BIO *bio_mem = NULL;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch const unsigned char *d;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch int ret;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch long p_size;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch char *p;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (der_blob == NULL || der_size == 0) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch return EINVAL;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch d = (const unsigned char *) der_blob;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
89bc31f70e51f4a69e0444c4f893831f6e96456eTimo Sirainen x509 = d2i_X509(NULL, &d, (int) der_size);
89bc31f70e51f4a69e0444c4f893831f6e96456eTimo Sirainen if (x509 == NULL) {
89bc31f70e51f4a69e0444c4f893831f6e96456eTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n");
89bc31f70e51f4a69e0444c4f893831f6e96456eTimo Sirainen return EINVAL;
89bc31f70e51f4a69e0444c4f893831f6e96456eTimo Sirainen }
89bc31f70e51f4a69e0444c4f893831f6e96456eTimo Sirainen
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch bio_mem = BIO_new(BIO_s_mem());
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (bio_mem == NULL) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n");
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = ENOMEM;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch goto done;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = PEM_write_bio_X509(bio_mem, x509);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (ret != 1) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch DEBUG(SSSDBG_OP_FAILURE, "PEM_write_bio_X509 failed.\n");
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = EIO;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch goto done;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch p_size = BIO_get_mem_data(bio_mem, &p);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (p_size == 0) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch DEBUG(SSSDBG_OP_FAILURE, "Unexpected PEM size [%ld].\n", p_size);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = EINVAL;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch goto done;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch if (pem != NULL) {
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch *pem = talloc_strndup(mem_ctx, p, p_size);
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch if (*pem == NULL) {
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch DEBUG(SSSDBG_OP_FAILURE, "talloc_memdup failed.\n");
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch ret = ENOMEM;
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch goto done;
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch }
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch }
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch if (pem_size != NULL) {
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch *pem_size = p_size;
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch }
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch ret = EOK;
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Boschdone:
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch X509_free(x509);
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch BIO_free_all(bio_mem);
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch return ret;
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch}
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Bosch
6407243c0b7340dd7b53b96bcb8e6b0e1acdb104Stephan Boscherrno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem,
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch uint8_t **_der_blob, size_t *_der_size)
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch{
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch X509 *x509 = NULL;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch BIO *bio_mem = NULL;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch int ret;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch unsigned char *buf;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch int buf_size;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch uint8_t *der_blob;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch size_t der_size;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (pem == NULL) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch return EINVAL;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch bio_mem = BIO_new(BIO_s_mem());
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (bio_mem == NULL) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n");
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = ENOMEM;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch goto done;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = BIO_puts(bio_mem, pem);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (ret <= 0) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch DEBUG(SSSDBG_OP_FAILURE, "BIO_puts failed.\n");
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = EIO;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch goto done;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch x509 = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (x509 == NULL) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch DEBUG(SSSDBG_OP_FAILURE, "PEM_read_bio_X509 failed.\n");
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = EIO;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch goto done;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch buf_size = i2d_X509(x509, NULL);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (buf_size <= 0) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch DEBUG(SSSDBG_OP_FAILURE, "i2d_X509 failed.\n");
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = EIO;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch goto done;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (_der_blob != NULL) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch buf = talloc_size(mem_ctx, buf_size);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (buf == NULL) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = ENOMEM;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch goto done;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch der_blob = buf;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch der_size = i2d_X509(x509, &buf);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (der_size != buf_size) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch talloc_free(der_blob);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch DEBUG(SSSDBG_CRIT_FAILURE,
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch "i2d_X509 size mismatch between two calls.\n");
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = EIO;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch goto done;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch *_der_blob = der_blob;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch if (_der_size != NULL) {
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch *_der_size = buf_size;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch }
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch ret = EOK;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Boschdone:
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch X509_free(x509);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch BIO_free_all(bio_mem);
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch return ret;
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch}
57e3b63a75335f45cf6cf9cd89317e2e6cec249dStephan Bosch