Block SecTpmMemory::signInTpm(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm) { if (digestAlgorithm != DIGEST_ALGORITHM_SHA256) return ConstBufferPtr(); // Find the private key and sign. PrivateKeyStore::iterator privateKey = privateKeyStore_.find(keyName.toUri()); if (privateKey == privateKeyStore_.end()) throw Error(string("MemoryPrivateKeyStorage: Cannot find private key ") + keyName.toUri()); uint8_t digest[SHA256_DIGEST_LENGTH]; SHA256_CTX sha256; SHA256_Init(&sha256); SHA256_Update(&sha256, data, dataLength); SHA256_Final(digest, &sha256); BufferPtr signatureBuffer = ptr_lib::make_shared<Buffer>(); signatureBuffer->resize(RSA_size(privateKey->second->getPrivateKey())); unsigned int signatureBitsLength; if (!RSA_sign(NID_sha256, digest, sizeof(digest), signatureBuffer->buf(), &signatureBitsLength, privateKey->second->getPrivateKey())) { throw Error("Error in RSA_sign"); } return Block(Tlv::SignatureValue, signatureBuffer); }
BufferPtr BufferCache::alloc( const uint64_t size ) { LB_TS_SCOPED( _thread ); LBASSERTINFO( size >= COMMAND_ALLOCSIZE, size ); LBASSERTINFO( size < LB_BIT48, "Out-of-sync network stream: buffer size " << size << "?" ); BufferPtr buffer = _impl->newBuffer(); LBASSERT( buffer->getRefCount() == 1 ); buffer->reserve( size ); buffer->resize( 0 ); return buffer; }
bool Connection::recvSync( BufferPtr& outBuffer, const bool block ) { LBASSERTINFO( _impl->buffer, "No pending receive on " << getDescription()->toString( )); // reset async IO data outBuffer = _impl->buffer; const uint64_t bytes = _impl->bytes; _impl->buffer = 0; _impl->bytes = 0; if( _impl->state != STATE_CONNECTED || !outBuffer || bytes == 0 ) return false; LBASSERTINFO( bytes < LB_BIT48, "Out-of-sync network stream: read size " << bytes << "?" ); #ifdef STATISTICS _impl->inBytes += bytes; #endif // 'Iterators' for receive loop uint8_t* ptr = outBuffer->getData() + outBuffer->getSize(); uint64_t bytesLeft = bytes; int64_t got = readSync( ptr, bytesLeft, block ); // WAR: fluke notification: On Win32, we get occasionally a data // notification and then deadlock when reading from the connection. The // callee (Node::handleData) will flag the first read, the underlying // SocketConnection will not block and we will restore the AIO operation if // no data was present. if( got == READ_TIMEOUT ) { _impl->buffer = outBuffer; _impl->bytes = bytes; outBuffer = 0; return true; } // From here on, receive loop until all data read or error while( true ) { if( got < 0 ) // error { const uint64_t read = bytes - bytesLeft; outBuffer->resize( outBuffer->getSize() + read ); if( bytes == bytesLeft ) LBDEBUG << "Read on dead connection" << std::endl; else LBERROR << "Error during read after " << read << " bytes on " << _impl->description << std::endl; return false; } else if( got == 0 ) { // ConnectionSet::select may report data on an 'empty' connection. // If we have nothing read so far, we have hit this case. if( bytes == bytesLeft ) return false; LBVERB << "Zero bytes read" << std::endl; } if( bytesLeft > static_cast< uint64_t >( got )) // partial read { ptr += got; bytesLeft -= got; readNB( ptr, bytesLeft ); got = readSync( ptr, bytesLeft, true ); continue; } // read done LBASSERTINFO( static_cast< uint64_t >( got ) == bytesLeft, got << " != " << bytesLeft ); outBuffer->resize( outBuffer->getSize() + bytes ); #ifndef NDEBUG if( bytes <= 1024 && ( lunchbox::Log::topics & LOG_PACKETS )) { ptr -= (bytes - bytesLeft); // rewind LBINFO << "recv:" << lunchbox::format( ptr, bytes ) << std::endl; } #endif return true; } LBUNREACHABLE; return true; }