Class: RubyTls::SSL::Box

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-tls/ssl.rb

Constant Summary collapse

READ_BUFFER =
2048
SSL_VERIFY_PEER =
0x01
SSL_VERIFY_CLIENT_ONCE =
0x04
SSL_ERROR_WANT_READ =
2
SSL_ERROR_SSL =
1
SSL_RECEIVED_SHUTDOWN =
2

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server, transport, options = {}) ⇒ Box

Returns a new instance of Box.



345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/ruby-tls/ssl.rb', line 345

def initialize(server, transport, options = {})
    @ready = true

    @handshake_completed = false
    @handshake_signaled = false
    @transport = transport

    @read_buffer = FFI::MemoryPointer.new(:char, READ_BUFFER, false)

    @is_server = server
    @context = Context.new(server, options)
    @bioRead = SSL.BIO_new(SSL.BIO_s_mem)
    @bioWrite = SSL.BIO_new(SSL.BIO_s_mem)
    @ssl = SSL.SSL_new(@context.ssl_ctx)
    SSL.SSL_set_bio(@ssl, @bioRead, @bioWrite)

    @write_queue = []

    # TODO:: if server && options[:alpn_string]
    # SSL_CTX_set_alpn_select_cb

    InstanceLookup[@ssl.address] = self

    if options[:verify_peer]
        SSL.SSL_set_verify(@ssl, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, VerifyCB)
    end

    SSL.SSL_connect(@ssl) unless server
end

Instance Attribute Details

#handshake_completedObject (readonly)

Returns the value of attribute handshake_completed.



377
378
379
# File 'lib/ruby-tls/ssl.rb', line 377

def handshake_completed
  @handshake_completed
end

#is_serverObject (readonly)

Returns the value of attribute is_server.



376
377
378
# File 'lib/ruby-tls/ssl.rb', line 376

def is_server
  @is_server
end

Instance Method Details

#cleanupObject



442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'lib/ruby-tls/ssl.rb', line 442

def cleanup
    @ready = false

    InstanceLookup.delete @ssl.address

    if (SSL.SSL_get_shutdown(@ssl) & SSL_RECEIVED_SHUTDOWN) != 0
        SSL.SSL_shutdown @ssl
    else
        SSL.SSL_clear @ssl
    end

    SSL.SSL_free @ssl

    @context.cleanup
end

#decrypt(data) ⇒ Object



404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/ruby-tls/ssl.rb', line 404

def decrypt(data)
    return unless @ready

    put_cipher_text data

    if not SSL.SSL_is_init_finished(@ssl)
        resp = @is_server ? SSL.SSL_accept(@ssl) : SSL.SSL_connect(@ssl)

        if resp < 0
            err_code = SSL.SSL_get_error(@ssl, resp)
            if err_code != SSL_ERROR_WANT_READ
                @transport.close_cb if err_code == SSL_ERROR_SSL
                return
            end
        end

        @handshake_completed = true
        signal_handshake unless @handshake_signaled
    end

    while true do
        size = get_plain_text(@read_buffer, READ_BUFFER)
        if size > 0
            @transport.dispatch_cb @read_buffer.read_string(size)
        else
            break
        end
    end

    dispatch_cipher_text
end

#encrypt(data) ⇒ Object



391
392
393
394
395
396
397
398
399
400
# File 'lib/ruby-tls/ssl.rb', line 391

def encrypt(data)
    return unless @ready

    wrote = put_plain_text data
    if wrote < 0
        @transport.close_cb
    else
        dispatch_cipher_text
    end
end

#get_peer_certObject



380
381
382
383
# File 'lib/ruby-tls/ssl.rb', line 380

def get_peer_cert
    return '' unless @ready
    SSL.SSL_get_peer_certificate(@ssl)
end

#signal_handshakeObject



436
437
438
439
# File 'lib/ruby-tls/ssl.rb', line 436

def signal_handshake
    @handshake_signaled = true
    @transport.handshake_cb
end

#startObject



385
386
387
388
389
# File 'lib/ruby-tls/ssl.rb', line 385

def start
    return unless @ready

    dispatch_cipher_text
end

#verify(cert) ⇒ Object

Called from class level callback function



459
460
461
# File 'lib/ruby-tls/ssl.rb', line 459

def verify(cert)
    @transport.verify_cb(cert) == true ? 1 : 0
end