1f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// Copyright 2014 The Chromium Authors. All rights reserved. 2f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// Use of this source code is governed by a BSD-style license that can be 3f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko// found in the LICENSE file. 4f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 5f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include "crypto/openssl_bio_string.h" 6f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 7f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include <openssl/bio.h> 8f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko#include <string.h> 9f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 10f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkonamespace crypto { 11f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 12f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkonamespace { 13f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 14f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkoint bio_string_write(BIO* bio, const char* data, int len) { 15f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko reinterpret_cast<std::string*>(bio->ptr)->append(data, len); 16f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return len; 17f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko} 18f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 19f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkoint bio_string_puts(BIO* bio, const char* data) { 20f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko // Note: unlike puts(), BIO_puts does not add a newline. 21f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return bio_string_write(bio, data, strlen(data)); 22f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko} 23f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 24f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkolong bio_string_ctrl(BIO* bio, int cmd, long num, void* ptr) { 25f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko std::string* str = reinterpret_cast<std::string*>(bio->ptr); 26f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko switch (cmd) { 27f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko case BIO_CTRL_RESET: 28f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko str->clear(); 29f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return 1; 30f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko case BIO_C_FILE_SEEK: 31f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return -1; 32f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko case BIO_C_FILE_TELL: 33f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return str->size(); 34f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko case BIO_CTRL_FLUSH: 35f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return 1; 36f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko default: 37f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return 0; 38f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko } 39f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko} 40f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 41f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkoint bio_string_new(BIO* bio) { 42f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko bio->ptr = NULL; 43f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko bio->init = 0; 44f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return 1; 45f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko} 46f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 47f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenkoint bio_string_free(BIO* bio) { 48f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko // The string is owned by the caller, so there's nothing to do here. 49f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return bio != NULL; 50f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko} 51f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 52f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex VakulenkoBIO_METHOD bio_string_methods = { 53f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko // TODO(mattm): Should add some type number too? (bio.h uses 1-24) 54f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko BIO_TYPE_SOURCE_SINK, 55f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko "bio_string", 56f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko bio_string_write, 57f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko NULL, /* read */ 58f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko bio_string_puts, 59f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko NULL, /* gets */ 60f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko bio_string_ctrl, 61f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko bio_string_new, 62f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko bio_string_free, 63f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko NULL, /* callback_ctrl */ 64f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko}; 65f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 66f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko} // namespace 67f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 68f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex VakulenkoBIO* BIO_new_string(std::string* out) { 69f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko BIO* bio = BIO_new(&bio_string_methods); 70f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko if (!bio) 71f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return bio; 72f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko bio->ptr = out; 73f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko bio->init = 1; 74f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko return bio; 75f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko} 76f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko 77f6024733c0d1eed88f68520b5e6a20b96e212ad6Alex Vakulenko} // namespace crypto 78