cert.c revision 544a20de7667f05c1a406c4dea0706b0ab507430
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/*
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen SSSD - certificate handling utils - openssl version
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen Copyright (C) Sumit Bose <sbose@redhat.com> 2015
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen This program is free software; you can redistribute it and/or modify
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen it under the terms of the GNU General Public License as published by
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen the Free Software Foundation; either version 3 of the License, or
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen (at your option) any later version.
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
3ba9a079592f46e94ce846e5aa80e4d479cd5e41Timo Sirainen This program is distributed in the hope that it will be useful,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen GNU General Public License for more details.
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen You should have received a copy of the GNU General Public License
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen*/
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen#include <openssl/x509.h>
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen#include <openssl/bio.h>
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen#include <openssl/pem.h>
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen#include "util/util.h"
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenerrno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen size_t der_size, char **pem, size_t *pem_size)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen X509 *x509 = NULL;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen BIO *bio_mem = NULL;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen const unsigned char *d;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen int ret;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen long p_size;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen char *p;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen if (der_blob == NULL || der_size == 0) {
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen return EINVAL;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
3ba9a079592f46e94ce846e5aa80e4d479cd5e41Timo Sirainen d = (const unsigned char *) der_blob;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen x509 = d2i_X509(NULL, &d, (int) der_size);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (x509 == NULL) {
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n");
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen return EINVAL;
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen bio_mem = BIO_new(BIO_s_mem());
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (bio_mem == NULL) {
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = ENOMEM;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen goto done;
3ba9a079592f46e94ce846e5aa80e4d479cd5e41Timo Sirainen }
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = PEM_write_bio_X509(bio_mem, x509);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (ret != 1) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "PEM_write_bio_X509 failed.\n");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = EIO;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen goto done;
3ba9a079592f46e94ce846e5aa80e4d479cd5e41Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen p_size = BIO_get_mem_data(bio_mem, &p);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen if (p_size == 0) {
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "Unexpected PEM size [%ld].\n", p_size);
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen ret = EINVAL;
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen goto done;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (pem != NULL) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *pem = talloc_strndup(mem_ctx, p, p_size);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (*pem == NULL) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "talloc_memdup failed.\n");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = ENOMEM;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen goto done;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen }
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen if (pem_size != NULL) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *pem_size = p_size;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = EOK;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainendone:
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen X509_free(x509);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen BIO_free_all(bio_mem);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return ret;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen}
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenerrno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen uint8_t **_der_blob, size_t *_der_size)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen{
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen X509 *x509 = NULL;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen BIO *bio_mem = NULL;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen int ret;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen unsigned char *buf;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen int buf_size;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen uint8_t *der_blob;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen size_t der_size;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (pem == NULL) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen return EINVAL;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen bio_mem = BIO_new(BIO_s_mem());
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (bio_mem == NULL) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = ENOMEM;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen goto done;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = BIO_puts(bio_mem, pem);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (ret <= 0) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "BIO_puts failed.\n");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = EIO;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen goto done;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen x509 = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (x509 == NULL) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "PEM_read_bio_X509 failed.\n");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = EIO;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen goto done;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen buf_size = i2d_X509(x509, NULL);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (buf_size <= 0) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "i2d_X509 failed.\n");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = EIO;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen goto done;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (_der_blob != NULL) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen buf = talloc_size(mem_ctx, buf_size);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (buf == NULL) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = ENOMEM;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen goto done;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen der_blob = buf;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
47f1c273dfaea552c034ffbecdec096f7cbaef35Timo Sirainen der_size = i2d_X509(x509, &buf);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (der_size != buf_size) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen talloc_free(der_blob);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen "i2d_X509 size mismatch between two calls.\n");
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = EIO;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen goto done;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *_der_blob = der_blob;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen if (_der_size != NULL) {
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen *_der_size = buf_size;
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen }
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen ret = EOK;
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainendone:
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen X509_free(x509);
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen BIO_free_all(bio_mem);
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen return ret;
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen}
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen#define SSH_RSA_HEADER "ssh-rsa"
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen#define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1)
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainenerrno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db,
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen const uint8_t *der_blob, size_t der_size,
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen bool do_ocsp,
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen uint8_t **key, size_t *key_size)
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen{
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen int ret;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen size_t size;
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen const unsigned char *d;
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen uint8_t *buf = NULL;
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen size_t c;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen X509 *cert = NULL;
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen EVP_PKEY *cert_pub_key = NULL;
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen int modulus_len;
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen unsigned char modulus[OPENSSL_RSA_MAX_MODULUS_BITS/8];
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen int exponent_len;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen unsigned char exponent[OPENSSL_RSA_MAX_PUBEXP_BITS/8];
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen if (der_blob == NULL || der_size == 0) {
7891c8e6debdcfec552cb1beea2a0230fe89957bTimo Sirainen return EINVAL;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen }
f096367f0f7b0e481f8abe0969afdf2d8250057eTimo Sirainen
f096367f0f7b0e481f8abe0969afdf2d8250057eTimo Sirainen d = (const unsigned char *) der_blob;
f096367f0f7b0e481f8abe0969afdf2d8250057eTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen cert = d2i_X509(NULL, &d, (int) der_size);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen if (cert == NULL) {
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n");
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen return EINVAL;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen }
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen /* TODO: verify certificate !!!!! */
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen cert_pub_key = X509_get_pubkey(cert);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen if (cert_pub_key == NULL) {
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "X509_get_pubkey failed.\n");
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen ret = EIO;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen goto done;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen }
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen if (cert_pub_key->type != EVP_PKEY_RSA) {
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen DEBUG(SSSDBG_CRIT_FAILURE,
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen "Expected RSA public key, found unsupported [%d].\n",
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen cert_pub_key->type);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen ret = EINVAL;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen goto done;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen }
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen modulus_len = BN_bn2bin(cert_pub_key->pkey.rsa->n, modulus);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen exponent_len = BN_bn2bin(cert_pub_key->pkey.rsa->e, exponent);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen size = SSH_RSA_HEADER_LEN + 3 * sizeof(uint32_t)
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen + modulus_len
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen + exponent_len
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen + 1; /* see comment about missing 00 below */
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen buf = talloc_size(mem_ctx, size);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen if (buf == NULL) {
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen ret = ENOMEM;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen goto done;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen }
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen c = 0;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen SAFEALIGN_SET_UINT32(buf, htobe32(SSH_RSA_HEADER_LEN), &c);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen safealign_memcpy(&buf[c], SSH_RSA_HEADER, SSH_RSA_HEADER_LEN, &c);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen SAFEALIGN_SET_UINT32(&buf[c], htobe32(exponent_len), &c);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen safealign_memcpy(&buf[c], exponent, exponent_len, &c);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen /* Adding missing 00 which afaik is added to make sure
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen * the bigint is handled as positive number */
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen /* TODO: make a better check if 00 must be added or not, e.g. ... & 0x80)
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen */
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen SAFEALIGN_SET_UINT32(&buf[c], htobe32(modulus_len + 1), &c);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen SAFEALIGN_SETMEM_VALUE(&buf[c], '\0', unsigned char, &c);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen safealign_memcpy(&buf[c], modulus, modulus_len, &c);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen *key = buf;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen *key_size = size;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen ret = EOK;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainendone:
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen if (ret != EOK) {
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen talloc_free(buf);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen }
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen EVP_PKEY_free(cert_pub_key);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen X509_free(cert);
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen return ret;
1d3b9fce06b466bcf64f9ab7b622f3a6e4e939baTimo Sirainen}
4e56e6408815c04f2e5b904a648a366a2dcbd408Timo Sirainen