ultimatepp/uppsrc/Core/SSL/Util.cpp
cxl ed5302e09c uppsrc: Fixed many Win64 warnings
git-svn-id: svn://ultimatepp.org/upp/trunk@5821 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2013-02-18 09:30:12 +00:00

208 lines
4.2 KiB
C++

#include "SSL.h"
NAMESPACE_UPP
String SslBuffer::Get() const
{
if(IsEmpty())
return String::GetVoid();
return String(buf_mem->data, (int)buf_mem->length);
}
bool SslBuffer::Grow(int length)
{
return !IsEmpty() && BUF_MEM_grow(buf_mem, length);
}
bool SslBuffer::Set(const String& d)
{
if(!buf_mem && !Create())
return false;
int len = d.GetLength();
if((int)buf_mem->max < len && !Grow(len))
return false;
ASSERT((int)buf_mem->max >= len);
buf_mem->length = len;
memcpy(buf_mem, d, len);
return true;
}
bool SslStream::OpenBuffer(const char *data, int length)
{
return Set(BIO_new_mem_buf(const_cast<char *>(data), length));
}
bool SslStream::CreateBuffer()
{
Clear();
SslBuffer buf;
if(!buf.Create() || !Create(BIO_s_mem()))
return false;
BIO_set_mem_buf(bio, buf.Detach(), BIO_CLOSE);
return true;
}
String SslStream::GetResult() const
{
if(IsEmpty())
return String::GetVoid();
BUF_MEM *bm = NULL;
BIO_get_mem_ptr(bio, &bm);
if(!bm)
return String::GetVoid();
return String(bm->data, (int)bm->length);
}
bool SslKey::Load(const String& data)
{
Clear();
SslStream strm;
if(!strm.OpenBuffer(data.Begin(), data.GetLength()))
return false;
return Set(PEM_read_bio_PrivateKey(strm, NULL, NULL, NULL));
}
bool SslCertificate::Load(const String& data, bool asn1)
{
Clear();
SslStream in, pem, *sio = &in;
if(!in.OpenBuffer(data, data.GetLength()))
return false;
if(!asn1)
{
if(!pem.Create(BIO_f_base64()))
return false;
BIO_push(pem, in);
sio = &pem;
}
return Set(d2i_X509_bio(*sio, NULL));
}
String SslCertificate::Save(bool asn1) const
{
if(IsEmpty())
return String::GetVoid();
SslStream out, pem, *sio = &out;
if(!out.CreateBuffer())
return String::GetVoid();
if(!asn1)
{
if(!pem.Create(BIO_f_base64()))
return String::GetVoid();
BIO_push(pem, out);
sio = &pem;
}
i2d_X509_bio(*sio, cert);
return out.GetResult();
}
String SslCertificate::GetSubjectName() const
{
ASSERT(!IsEmpty());
return SslToString(X509_get_subject_name(cert));
}
String SslCertificate::GetIssuerName() const
{
ASSERT(!IsEmpty());
return SslToString(X509_get_issuer_name(cert));
}
Date SslCertificate::GetNotBefore() const
{
ASSERT(!IsEmpty());
return Asn1ToDate(X509_get_notBefore(cert));
}
Date SslCertificate::GetNotAfter() const
{
ASSERT(!IsEmpty());
return Asn1ToDate(X509_get_notAfter(cert));
}
int SslCertificate::GetVersion() const
{
ASSERT(!IsEmpty());
return X509_get_version(cert);
}
String SslCertificate::GetSerialNumber() const
{
ASSERT(!IsEmpty());
return Asn1ToString(X509_get_serialNumber(cert));
}
SslContext::SslContext(SSL_CTX *c)
: ssl_ctx(c)
{
SslInitThread();
}
bool SslContext::CipherList(const char *list)
{
ASSERT(ssl_ctx);
return SSL_CTX_set_cipher_list(ssl_ctx, list);
}
bool SslContext::UseCertificate(String certdata, String pkeydata, bool cert_asn1)
{
ASSERT(ssl_ctx);
if(IsNull(certdata) || IsNull(pkeydata))
return false;
SslCertificate cert;
SslKey pkey;
if(!cert.Load(certdata, cert_asn1) || !pkey.Load(pkeydata))
return false;
if(!SSL_CTX_use_certificate(ssl_ctx, cert) || !SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
return false;
if(!SSL_CTX_check_private_key(ssl_ctx))
return false;
return true;
}
void SslContext::VerifyPeer(bool verify, int depth)
{
ASSERT(ssl_ctx);
SSL_CTX_set_verify(ssl_ctx, verify ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
SSL_CTX_set_verify_depth(ssl_ctx, depth);
}
String SslGetLastError(int& code)
{
char errbuf[150];
ERR_error_string(code = ERR_get_error(), errbuf);
return errbuf;
}
String SslGetLastError()
{
int dummy;
return SslGetLastError(dummy);
}
String SslToString(X509_NAME *name)
{
char buffer[500];
return X509_NAME_oneline(name, buffer, sizeof(buffer));
}
Date Asn1ToDate(ASN1_STRING *time)
{
if(!time) return Null;
int digit = 0;
while(digit < time->length && IsDigit(time->data[digit]))
digit++;
if(digit < 6)
return Null;
int year2 = time->data[0] * 10 + time->data[1] - 11 * '0';
int month = time->data[2] * 10 + time->data[3] - 11 * '0';
int day = time->data[4] * 10 + time->data[5] - 11 * '0';
return Date(year2 + (year2 < 90 ? 2000 : 1900), month, day);
}
String Asn1ToString(ASN1_STRING *s)
{
return String(s->data, s->length);
}
END_UPP_NAMESPACE