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