diff --git a/headers/os/net/Certificate.h b/headers/os/net/Certificate.h index 003c6415a2..7be21b32a1 100644 --- a/headers/os/net/Certificate.h +++ b/headers/os/net/Certificate.h @@ -14,12 +14,19 @@ class BCertificate { public: ~BCertificate(); - BString String(); + int Version(); time_t StartDate(); time_t ExpirationDate(); + + bool IsValidAuthority(); + bool IsSelfSigned(); + BString Issuer(); BString Subject(); + BString SignatureAlgorithm(); + + BString String(); private: friend class BSecureSocket::Private; diff --git a/headers/os/net/SecureSocket.h b/headers/os/net/SecureSocket.h index 5b54ed4c76..09d3c300ad 100644 --- a/headers/os/net/SecureSocket.h +++ b/headers/os/net/SecureSocket.h @@ -21,7 +21,7 @@ public: virtual ~BSecureSocket(); virtual bool CertificateVerificationFailed(BCertificate& - certificate); + certificate, const char* message); // BSocket implementation diff --git a/src/kits/network/libnetapi/Certificate.cpp b/src/kits/network/libnetapi/Certificate.cpp index b7fdc7ccf8..290a9bb07c 100644 --- a/src/kits/network/libnetapi/Certificate.cpp +++ b/src/kits/network/libnetapi/Certificate.cpp @@ -14,6 +14,9 @@ #ifdef OPENSSL_ENABLED +#include + + static time_t parse_ASN1(ASN1_GENERALIZEDTIME *asn1) { @@ -61,18 +64,10 @@ BCertificate::~BCertificate() } -BString -BCertificate::String() +int +BCertificate::Version() { - BIO *buffer = BIO_new(BIO_s_mem()); - X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT); - - char* pointer; - long length = BIO_get_mem_data(buffer, &pointer); - BString result(pointer, length); - - BIO_free(buffer); - return result; + return X509_get_version(fPrivate->fX509) + 1; } @@ -90,6 +85,20 @@ BCertificate::ExpirationDate() } +bool +BCertificate::IsValidAuthority() +{ + return X509_check_ca(fPrivate->fX509) > 0; +} + + +bool +BCertificate::IsSelfSigned() +{ + return X509_check_issued(fPrivate->fX509, fPrivate->fX509) == X509_V_OK; +} + + BString BCertificate::Issuer() { @@ -106,6 +115,35 @@ BCertificate::Subject() } +BString +BCertificate::SignatureAlgorithm() +{ + int algorithmIdentifier = OBJ_obj2nid( + fPrivate->fX509->cert_info->key->algor->algorithm); + + if (algorithmIdentifier == NID_undef) + return BString("undefined"); + + const char* buffer = OBJ_nid2ln(algorithmIdentifier); + return BString(buffer); +} + + +BString +BCertificate::String() +{ + BIO *buffer = BIO_new(BIO_s_mem()); + X509_print_ex(buffer, fPrivate->fX509, XN_FLAG_COMPAT, X509_FLAG_COMPAT); + + char* pointer; + long length = BIO_get_mem_data(buffer, &pointer); + BString result(pointer, length); + + BIO_free(buffer); + return result; +} + + // #pragma mark - BCertificate::Private @@ -128,13 +166,6 @@ BCertificate::~BCertificate() } -BString -BCertificate::String() -{ - return BString(); -} - - time_t BCertificate::StartDate() { @@ -149,6 +180,20 @@ BCertificate::ExpirationDate() } +bool +BCertificate::IsValidAuthority() +{ + return false; +} + + +int +BCertificate::Version() +{ + return B_NOT_SUPPORTED; +} + + BString BCertificate::Issuer() { @@ -163,4 +208,18 @@ BCertificate::Subject() } +BString +BCertificate::SignatureAlgorithm() +{ + return BString(); +} + + +BString +BCertificate::String() +{ + return BString(); +} + + #endif diff --git a/src/kits/network/libnetapi/SecureSocket.cpp b/src/kits/network/libnetapi/SecureSocket.cpp index a97bcf1ae3..3c7e359994 100644 --- a/src/kits/network/libnetapi/SecureSocket.cpp +++ b/src/kits/network/libnetapi/SecureSocket.cpp @@ -156,9 +156,12 @@ BSecureSocket::Private::VerifyCallback(int ok, X509_STORE_CTX* ctx) if (certificate == NULL) return 0; + int error = X509_STORE_CTX_get_error(ctx); + const char* message = X509_verify_cert_error_string(error); + // Let the BSecureSocket (or subclass) decide if we should continue anyway. BCertificate failedCertificate(certificate); - return socket->CertificateVerificationFailed(failedCertificate); + return socket->CertificateVerificationFailed(failedCertificate, message); } @@ -289,12 +292,11 @@ BSecureSocket::WaitForReadable(bigtime_t timeout) const bool -BSecureSocket::CertificateVerificationFailed(BCertificate& certificate) +BSecureSocket::CertificateVerificationFailed(BCertificate&, const char*) { // Until apps actually make use of the certificate API, let's keep the old // behavior and accept all connections, even if the certificate validation // didn't work. - (void)certificate; return true; }