#pragma once

#ifndef GEODE_CRYPTOIMPL_DHIMPL_H_
#define GEODE_CRYPTOIMPL_DHIMPL_H_

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <openssl/asn1t.h>
#include <openssl/dh.h>
#include <openssl/x509.h>

#include <cstring>
#include <string>
#include <vector>

#include "cryptoimpl_export.h"

#define DH_ERR_NO_ERROR 0
#define DH_ERR_UNSUPPORTED_ALGO 1
#define DH_ERR_ILLEGAL_KEYSIZE 2
#define DH_ERR_SUBJECT_NOT_FOUND 3
#define DH_ERR_NO_CERTIFICATES 4
#define DH_ERR_INVALID_SIGN 5

#ifdef _DEBUG
#define LOGDH printf
#else
#define LOGDH(...)
#endif

//  We need to declare our own structures and macros for
// DH public key x509 encoding because it's not available in
// OpenSSL yet.
typedef struct DH_pubkey_st {
  X509_ALGOR* algor;
  ASN1_BIT_STRING* public_key;
  EVP_PKEY* pkey;
} DH_PUBKEY;

extern "C" {
CRYPTOIMPL_EXPORT int gf_initDhKeys(void** dhCtx, const char* dhAlgo,
                                    const char* ksPath);
CRYPTOIMPL_EXPORT void gf_clearDhKeys(void* dhCtx);
CRYPTOIMPL_EXPORT unsigned char* gf_getPublicKey(void* dhCtx, int* len);
CRYPTOIMPL_EXPORT void gf_setPublicKeyOther(void* dhCtx,
                                            const unsigned char* pubkey,
                                            int length);
CRYPTOIMPL_EXPORT void gf_computeSharedSecret(void* dhCtx);
CRYPTOIMPL_EXPORT unsigned char* gf_encryptDH(void* dhCtx,
                                              const unsigned char* cleartext,
                                              int len, int* retLen);
CRYPTOIMPL_EXPORT unsigned char* gf_decryptDH(void* dhCtx,
                                              const unsigned char* cleartext,
                                              int len, int* retLen);
CRYPTOIMPL_EXPORT bool gf_verifyDH(void* dhCtx, const char* subject,
                                   const unsigned char* challenge,
                                   int challengeLen,
                                   const unsigned char* response,
                                   int responseLen, int* reason);
}

class DHImpl {
 public:
  DH* m_dh;
  std::string m_skAlgo;
  int m_keySize;
  BIGNUM* m_pubKeyOther;
  unsigned char m_key[128];
  std::vector<X509*> m_serverCerts;

  const EVP_CIPHER* getCipherFunc();
  int setSkAlgo(const char* skalgo);

  DHImpl() : m_dh(nullptr), m_keySize(0), m_pubKeyOther(nullptr) {
    /* adongre
     * CID 28924: Uninitialized scalar field (UNINIT_CTOR)
     */
    std::memset(m_key, 0, sizeof(m_key));
  }
  static bool m_init;
};

bool DHImpl::m_init = false;

#endif  // GEODE_CRYPTOIMPL_DHIMPL_H_
