// 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.
#pragma once

#include <string>

namespace kudu {
class Status;

namespace security {

//
// Set of certificates and private keys used for certificate generation
// and signing tests (declarations).  See the .cc file for the actual data.
//

// Valid root CA cerificate (PEM format).
extern const char kCaCert[];
// The private key (RSA, 2048 bits) for the certificate above.
// This is 2048 bit RSA key, in PEM format.
extern const char kCaPrivateKey[];
// The public part of the abovementioned private key.
extern const char kCaPublicKey[];

// Expired root CA certificate (PEM format).
extern const char kCaExpiredCert[];
// The private key for the expired CA certificate described above.
// This is 2048 bit RSA key, in PEM format.
extern const char kCaExpiredPrivateKey[];
// The public part of the abovementioned private key.
extern const char kCaExpiredPublicKey[];
// Certificate with multiple DNS hostnames in the SAN field.
extern const char kCertDnsHostnamesInSan[];

extern const char kDataTiny[];
extern const char kSignatureTinySHA512[];

extern const char kDataShort[];
extern const char kSignatureShortSHA512[];

extern const char kDataLong[];
extern const char kSignatureLongSHA512[];

// Creates a matching SSL certificate and unencrypted private key file in 'dir',
// returning their paths in '*cert_file' and '*key_file'.
Status CreateTestSSLCertWithPlainKey(const std::string& dir,
                                     std::string* cert_file,
                                     std::string* key_file);

// Same as the CreateTestSSLCertWithPlainKey() except that the private key is
// encrypted with a password that is returned in 'key_password'.
Status CreateTestSSLCertWithEncryptedKey(const std::string& dir,
                                         std::string* cert_file,
                                         std::string* key_file,
                                         std::string* key_password);

// Same as the CreateTestSSLCertWithPlainKey() except that the 'cert_file' is
// signed by a CA chain ('ca_cert_file' is a chain of certificates).
Status CreateTestSSLCertSignedByChain(const std::string& dir,
                                      std::string* cert_file,
                                      std::string* key_file,
                                      std::string* ca_cert_file);

// Same as the CreateTestSSLCertWithPlainKey() except that the 'cert_file' is
// a chain signed by a root CA ('ca_cert_file' is only the root CA).
Status CreateTestSSLCertWithChainSignedByRoot(const std::string& dir,
                                              std::string* cert_file,
                                              std::string* key_file,
                                              std::string* ca_cert_file);

} // namespace security
} // namespace kudu
