19f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler/*
29f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * Copyright (C) 2017 The Android Open Source Project
39f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler *
49f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * Licensed under the Apache License, Version 2.0 (the "License");
59f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * you may not use this file except in compliance with the License.
69f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * You may obtain a copy of the License at
79f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler *
89f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler *      http://www.apache.org/licenses/LICENSE-2.0
99f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler *
109f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * Unless required by applicable law or agreed to in writing, software
119f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * distributed under the License is distributed on an "AS IS" BASIS,
129f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * See the License for the specific language governing permissions and
149f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * limitations under the License.
159f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler */
169f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
179f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler#ifndef CONSCRYPT_OPENSSLERROR_H_
189f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler#define CONSCRYPT_OPENSSLERROR_H_
199f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
209f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler#include <openssl/ssl.h>
219f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
229f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittlernamespace conscrypt {
239f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
249f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler/**
259f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * Manages the freeing of the OpenSSL error stack. This allows you to
269f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * instantiate this object during an SSL call that may fail and not worry
279f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * about manually calling ERR_clear_error() later.
289f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler *
299f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * As an optimization, you can also call .release() for passing as an
309f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler * argument to things that free the error stack state as a side-effect.
319f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler */
329f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittlerclass OpenSslError {
339f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittlerpublic:
34c1e64b936526491fdc1836e7b0913f7514cdc378Kenny Root    OpenSslError() : sslError_(SSL_ERROR_NONE), released_(false) {}
359f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
369f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    OpenSslError(SSL* ssl, int returnCode) : sslError_(SSL_ERROR_NONE), released_(false) {
379f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler        reset(ssl, returnCode);
389f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    }
399f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
409f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    ~OpenSslError() {
419f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler        if (!released_ && sslError_ != SSL_ERROR_NONE) {
429f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler            ERR_clear_error();
439f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler        }
449f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    }
459f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
469f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    int get() const {
479f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler        return sslError_;
489f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    }
499f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
509f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    void reset(SSL* ssl, int returnCode) {
519f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler        if (returnCode <= 0) {
529f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler            sslError_ = SSL_get_error(ssl, returnCode);
539f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler        } else {
549f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler            sslError_ = SSL_ERROR_NONE;
559f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler        }
569f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    }
579f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
589f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    int release() {
599f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler        released_ = true;
609f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler        return sslError_;
619f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    }
629f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
639f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittlerprivate:
649f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    int sslError_;
659f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler    bool released_;
669f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler};
679f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
68c1e64b936526491fdc1836e7b0913f7514cdc378Kenny Root}  // namespace conscrypt
699f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler
709f80aec4d0a3986bb4506bbb1b51842a9a36f940Nathan Mittler#endif  // CONSCRYPT_OPENSSLERROR_H_
71