forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add OpenSSL BIO method that writes to a std::string.
BUG=none Review URL: https://codereview.chromium.org/286263006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272100 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
mattm@chromium.org
committed
May 22, 2014
1 parent
22a80ae
commit d46baaa
Showing
5 changed files
with
184 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "crypto/openssl_bio_string.h" | ||
|
||
#include <openssl/bio.h> | ||
#include <string.h> | ||
|
||
namespace crypto { | ||
|
||
namespace { | ||
|
||
int bio_string_write(BIO* bio, const char* data, int len) { | ||
reinterpret_cast<std::string*>(bio->ptr)->append(data, len); | ||
return len; | ||
} | ||
|
||
int bio_string_puts(BIO* bio, const char* data) { | ||
// Note: unlike puts(), BIO_puts does not add a newline. | ||
return bio_string_write(bio, data, strlen(data)); | ||
} | ||
|
||
long bio_string_ctrl(BIO* bio, int cmd, long num, void* ptr) { | ||
std::string* str = reinterpret_cast<std::string*>(bio->ptr); | ||
switch (cmd) { | ||
case BIO_CTRL_RESET: | ||
str->clear(); | ||
return 1; | ||
case BIO_C_FILE_SEEK: | ||
return -1; | ||
case BIO_C_FILE_TELL: | ||
return str->size(); | ||
case BIO_CTRL_FLUSH: | ||
return 1; | ||
default: | ||
return 0; | ||
} | ||
} | ||
|
||
int bio_string_new(BIO* bio) { | ||
bio->ptr = NULL; | ||
bio->init = 0; | ||
return 1; | ||
} | ||
|
||
int bio_string_free(BIO* bio) { | ||
// The string is owned by the caller, so there's nothing to do here. | ||
return bio != NULL; | ||
} | ||
|
||
BIO_METHOD bio_string_methods = { | ||
// TODO(mattm): Should add some type number too? (bio.h uses 1-24) | ||
BIO_TYPE_SOURCE_SINK, | ||
"bio_string", | ||
bio_string_write, | ||
NULL, /* read */ | ||
bio_string_puts, | ||
NULL, /* gets */ | ||
bio_string_ctrl, | ||
bio_string_new, | ||
bio_string_free, | ||
NULL, /* callback_ctrl */ | ||
}; | ||
|
||
} // namespace | ||
|
||
BIO* BIO_new_string(std::string* out) { | ||
BIO* bio = BIO_new(&bio_string_methods); | ||
if (!bio) | ||
return bio; | ||
bio->ptr = out; | ||
bio->init = 1; | ||
return bio; | ||
} | ||
|
||
} // namespace crypto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CRYPTO_OPENSSL_BIO_STRING_H_ | ||
#define CRYPTO_OPENSSL_BIO_STRING_H_ | ||
|
||
#include <string> | ||
|
||
#include "crypto/crypto_export.h" | ||
|
||
// From <openssl/bio.h> | ||
typedef struct bio_st BIO; | ||
|
||
namespace crypto { | ||
|
||
// Creates a new BIO that can be used with OpenSSL's various output functions, | ||
// and which will write all output directly into |out|. This is primarily | ||
// intended as a utility to reduce the amount of copying and separate | ||
// allocations when performing extensive string modifications or streaming | ||
// within OpenSSL. | ||
// | ||
// Note: |out| must remain valid for the duration of the BIO. | ||
BIO* CRYPTO_EXPORT BIO_new_string(std::string* out); | ||
|
||
} // namespace crypto | ||
|
||
#endif // CRYPTO_OPENSSL_BIO_STRING_H_ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright 2014 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "crypto/openssl_bio_string.h" | ||
|
||
#include <openssl/bio.h> | ||
|
||
#include "crypto/openssl_util.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
TEST(OpenSSLBIOString, TestWrite) { | ||
std::string s; | ||
const std::string expected1("a one\nb 2\n"); | ||
const std::string expected2("c d e f"); | ||
const std::string expected3("g h i"); | ||
{ | ||
crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&s)); | ||
ASSERT_TRUE(bio.get()); | ||
|
||
EXPECT_EQ(static_cast<int>(expected1.size()), | ||
BIO_printf(bio.get(), "a %s\nb %i\n", "one", 2)); | ||
EXPECT_EQ(expected1, s); | ||
EXPECT_EQ(static_cast<int>(expected1.size()), BIO_tell(bio.get())); | ||
|
||
EXPECT_EQ(1, BIO_flush(bio.get())); | ||
EXPECT_EQ(-1, BIO_seek(bio.get(), 0)); | ||
EXPECT_EQ(expected1, s); | ||
|
||
EXPECT_EQ(static_cast<int>(expected2.size()), | ||
BIO_write(bio.get(), expected2.data(), expected2.size())); | ||
EXPECT_EQ(expected1 + expected2, s); | ||
EXPECT_EQ(static_cast<int>(expected1.size() + expected2.size()), | ||
BIO_tell(bio.get())); | ||
|
||
EXPECT_EQ(static_cast<int>(expected3.size()), | ||
BIO_puts(bio.get(), expected3.c_str())); | ||
EXPECT_EQ(expected1 + expected2 + expected3, s); | ||
EXPECT_EQ(static_cast<int>(expected1.size() + expected2.size() + | ||
expected3.size()), | ||
BIO_tell(bio.get())); | ||
} | ||
EXPECT_EQ(expected1 + expected2 + expected3, s); | ||
} | ||
|
||
TEST(OpenSSLBIOString, TestReset) { | ||
std::string s; | ||
const std::string expected1("a b c\n"); | ||
const std::string expected2("d e f g\n"); | ||
{ | ||
crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(crypto::BIO_new_string(&s)); | ||
ASSERT_TRUE(bio.get()); | ||
|
||
EXPECT_EQ(static_cast<int>(expected1.size()), | ||
BIO_write(bio.get(), expected1.data(), expected1.size())); | ||
EXPECT_EQ(expected1, s); | ||
|
||
EXPECT_EQ(1, BIO_reset(bio.get())); | ||
EXPECT_EQ(std::string(), s); | ||
|
||
EXPECT_EQ(static_cast<int>(expected2.size()), | ||
BIO_write(bio.get(), expected2.data(), expected2.size())); | ||
EXPECT_EQ(expected2, s); | ||
} | ||
EXPECT_EQ(expected2, s); | ||
} |