$Id: README,v 1.14 2002/03/05 15:05:29 majkl Exp $
'OpenSSL for Ruby' project
Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
All rights reserved.
This program is licenced under the same licence as Ruby.
(See the file 'LICENCE'.)

['OpenSSL for Ruby' team members]
GOTOU Yuuzou <gotoyuzo@notwork.org> - SSL Socket implementation
Michal Rokos <m.rokos@sh.cvut.cz> - The rest (too long to enumerate), maintainer

[Contributors]
UNKNOWN <oss-ruby@technorama.net> - BN implementation core
Hynek Rostinsky <hynek.rostinsky@foresta.cz> - Windows platform fixes (strptime mainly)

[Done] (but not fully tested)
= PKey:: RSA,DSA keys - new, load, export
= X509::Certificate - generating new certs, load, looking inside
= X509::CRL - load, new, looking inside
= X509::Name - new, export, to_a, to_h (hash)
= X509::Revoked - new, looking inside (on parameters)
= X509::Store - new, import trusted certs and CRL, verifiing certs
= Digest::... - various hashes
= X509::Request - Cert requests
= X509::Attribute - as X509Request extensions (not tested)
= X509::Extension - to Certs, CRLs...
= X509::ExtensionMaker - for easy creating new Extensions
= Netscape::SPKI - for requests from NetscapeCommunicators
= Cipher::... - various ciphers
= basic PRNG functions (random generator) for OpenSSL module and class Random
= SSLSocket (merged Gotou Yuuzou's SSLsocket-Ruby project)
= PKCS7 (signing&data_verify is working, rest needs some testing)
= HMAC
= OpenSSL config file parser (part)
= BN (safe bignums)
= Diffie-Hellman

[To-Do]
= check for memory leaking :-))
= cleaner code
= examples
= RubyUnit to be used!
= API documentation
= comments to sources!!!
= further functionality to existing
= Std. Extensions, Attributes to be made as Classes?
= AttributeFactory?
= add aliases to to_pem as s_dump s_load to support Marshal module
= CipherFactory?
= autogen random IVs for Ciphers
= PKCS12
= PKCS8
= ASN.1 ???
= BIO ???
= compat tests for RSA/DSA sign/encrypt

[Requirements]
	Ruby	>= 1.6.4
	OpenSSL >= 0.9.6b

[Instalation]
= Unix like systems:
	ruby extconf.rb
	make
	su root -c make install

= Windows like systems:
	add to %PATH%: c:\openssl\bin (where the dlls lays)
	ruby extconf.rb --with-openssl-include=c:\openssl\include --with-openssl-lib=c:\openssl\lib
	(or ruby extconf.rb --with-openssl-dir=c:\openssl (NOT TESTED))
	nmake
	nmake install

[Documentation/API]
	Sorry, not done. See 'test' folder's examples and grep C sources for rb_define_*method :-))

--------------------------------------------------
=> XXX	- XXX is return value
A <=> B	- A is an alias to B
[XXX]	- argument XXX is optional
A|B	- argument can be A or B
bXXX	- XXX is true or false
cXXX	- XXX is defined as constant
fXXX	- XXX is Fixnum
hXXX	- XXX is Hash
nXXX	- XXX is Number (Fixnum or Bignum)
oXXX	- argument.kind_of?(XXX) => true
sXXX	- XXX is String
tXXX	- XXX is instance of Time
--------------------------------------------------
Integer
	.to_bn() => BN.new
	
OpenSSL::
	BN - Doc TODO!
		::new(...)
		--- PRIVATE ----------------------
		.initialize(arg, type="dec")
		.from_integer(arg, type="dec")
		.from_string(arg, type="dec")
		.from_bn(arg, dummy=nil)
		.from_s_bin(sBIN)
		.from_s_mpi(sMPI)
		.from_s_dec(sDEC)
		.from_s_hex(sHEX)
		--- PUBLIC -----------------------
		.to_s(type="dec") => sDEC
		.to_s_bin() => sBIN
		.to_s_mpi() => sMPI
		.to_s_dec() => sDEC
		.to_s_hex() => sHEX

	BNError
	
	Cipher::
		constants:	UNSPEC
			modes:	ECB, CFB, OFB, CBC
			types:	EDE, EDE3, BIT40, BIT64

		BlowFish (allowed: ECB, CFB, OFB, CBC)
		Cast5 (ECB, CFB, OFB, CBC)
		DES (ECB, EDE, EDE3, CFB, CFB:EDE, CFB:EDE3, OFB, OFB:EDE, OFB:EDE3, CBC, CBC:EDE, CBC:EDE3)
		Idea (ECB, CFB, OFB, CBC)
		RC2 (ECB, CBC, BIT40:CBC, BIT64:CBC, CFB, OFB)
		RC4 (nil, UNSPEC, BIT40)
		RC5 (ECB, CFB, OFB, CBC)
			::new([cMode|cType] [,cType|cMode])
			----------------------------------
			.encrypt(sPassword [, sInitVector]) => self
			.decrypt(sPassword [, sInitVector]) => self
			.update(sData) => s(En|De)crypted
			.<< <=> .update
			.cipher() => s(En|De)cryptedFinal
			
		CipherError
		
	Config
		::new(sFilename) - dispatches .load
		::load(sFilename)
		----------------------------------
		.get_value(sSection|nil, sKey) => sValue
		.get_section(sSection) => hSection
		
	ConfigError
			
	Digest::
		MD2
		MD4
		MD5
		MDC2
		RIPEMD160
		SHA
		SHA1
		DSS
		DSS1
			::new([sData])
			----------------------------------
			.update(sData) => self
			.<< <=> .update
			.digest() => sDigestFinal
			.hexdigest() => sHEXDigestFinal
			.inspect <=> .hexdigest
			.to_s <=> .hexdigest
			
		DigestError

	HMAC
		::new(sKey, oDigest::ANY) => self
		----------------------------------
		.update(sData) => self
		.<< <=> .update
		.hmac() => sHMACFinal
		.hexhmac() => sHEXHMACFinal
		.inspect <=> .hexhmac
		.to_s <=> .hexhmac
		
	HMACError
		
	Netscape::
		SPKI
			::new([sPEM])
			----------------------------------
			.to_pem() => sPEM
			.to_s <=> .to_pem
			.to_text() => sHumanReadable
			.public_key() => oPKey::ANY
			.public_key=(oPKey::ANY) => oPKey::ANY
			.sign(oPKey::ANY, oDigest::ANY) => self
			.verify(oPKey::ANY) => bResult
			.challenge() => sChallenge
			.challenge=(sChallenge) => sChallenge
			
		SPKIError

	PKCS7::
		constants:
			type:	SIGNED, ENVELOPED, SIGNED_ENVELOPED

		PKCS7
			::new(cType|sPEM)
			----------------------------------
			.cipher=(oCipher::ANY) => oCipher::ANY
			.add_signer(oPKCS7::Signer, oPKey::ANY) => self
			.signers() => Array of PKCS7::Signer
			.add_recipient(oX509::Certificate) => self
			.add_certificate(oX509::Certificate) => self
			.add_crl(oX509::CRL) => self
			.add_data(sData [, bDetached]) => self
			.verify_data(oX509::Store [, sDetachedData]) => bResult, yields PKCS7::Signer
			.decode_data(oPKey::ANY, oX509::Certificate) => sData
			.to_pem() => sPEM
			.to_s <=> .to_pem

		Signer
			::new(oX509::Certificate, oPKey::ANY, oDigest::ANY)
			----------------------------------
			.name() => X509::Name
			.serial() => fSerial
			.signed_time() => tTime

		PKCS7Error
		
	PKey::
		PKeyError
		
		DH
			::new((fLen|sPEM) [, fGenerator=2]) - dispatches .new_from_pem or .generate
			::new_from_pem(sPEM)
			::generate(fLen, fGenerator) - yields |p,n|
			::new_from_fixnum <=> ::generate
			----------------------------------
			.public?() => bResult
			.private?() => bResult
			.to_text() => sHumanReadable
			.export() => sPEM
			.to_pem <=> .export
			.public_key() => oPKey::ANY

		DSA
			::new([fKeyLen|sPEM [, sPassword]]) - dispatches .new_from_pem or .generate 
			::new_from_pem(sPEM [, sPassword])
			::generate(fKeyLen) - yields |p,n|
			::new_from_fixnum <=> generate
			----------------------------------
			.public?() => bResult
			.private?() => bResult
			.to_text() => sHumanReadable
			.export([oCipher::ANY [, sPassword]]) => sPEM
			.to_pem <=> .export
			.public_key() => oPKey::DSA
			.to_der() => sDER
			.sign(oDigest::ANY, sData) => sSig
			.sign_digest(sDigest) => sSig
			.verify(oDigest::ANY, sData, sSig) => bResult
			.verify_digest(sDigest, sSig) => bResult

		DSAError
			
		RSA
			::new([fKeyLen|sPEM [, sPassword]]) - dispatches .new_from_pem or .generate 
			::new_from_pem(sPEM [, sPassword])
			::generate(fKeyLen) - yields |p,n|
			::new_from_fixnum <=> generate
			----------------------------------
			.public?() => bResult
			.private?() => bResult
			.to_text() => sHumanReadable
			.export([oCipher::ANY [, sPassword]]) => sPEM
			.to_pem <=> .export
			.public_key() => oPKey::ANY
			.public_encrypt(sData) => sEnc
			.public_decrypt(sEnrypted) => sData
			.private_encrypt(sData) => sEnc
			.private_decrypt(sEncrypted) => sData
			.to_der() => sDER
			.sign(oDigest::ANY, sData) => sSig
			.verify(oDigest::ANY, sData, sSig) => bResult

		RSAError

	Random
		.seed(sSeed) => sSeed
		.load_random_file(sFilename) => bResult
		.write_random_file(sFilename) => bResult
		.random_bytes(fLen) => sRandom
		.egd(sUNIXSocketPath) => bResult
		.egd_bytes(sUNIXSocketPath, fLen) => bResult
	
	RandomError
	
	SSL:: - Doc TODO!

		Error
		
	X509::
		Attribute
			::new(arg) - dispatches "new_from_#{arg.type.name.downcase}"
			::new_from_string("oid = value")
			::new_from_array(["oid", "value"])
			::new_from_hash({"oid"=>"oid", "value"=>"val"})
			----------------------------------
			
		AttributeError
		
		Certificate - Doc TODO!
			.to_s <=> .to_pem
			
		CertificateError
		
		CRL - Doc TODO!
			.to_s <=> .to_pem
		
		CRLError
		
		Extension - Doc TODO!
			::new is DISABLED!
			----------------------------------
			.to_s => string as "oid = critical, value"
			.to_a => ary as ["oid", "value", critical], critical as bool
			.to_h => hash as {"oid"=>"oid", "value"=>"val", "critical"=>bool}
			
		ExtensionFactory - Doc TODO!
			::new(...)
			----------------------------------
			.create_extension(*arg)
			.create_ext_from_string(str)
			.create_ext_from_ary(ary) => X509::Extension, ary as ["oid", "value", critical], critical as bool
			.create_ext_from_hash(hash)
			
		ExtensionError
		
		Name - Doc TODO!
			::new(arg) dispatches "new_from_#{arg.type.name.downcase}"
			::new_from_string(str) => self, str as "/A=B/C=D/E=F"
			::new_from_array(ary) => self, ary as [["A","B"],["C","D"],["E","F"]]
			::new_from_hash(hash) => self, hash as {"A"=>"B","C"=>"D","E"=>"F"}
			----------------------------------
			.to_s => str as "/A=B/C=D/E=F"
			.to_a => ary as [["A","B"],["C","D"],["E","F"]]
			.to_h => hash as {"A"=>"B","C"=>"D","E"=>"F"}
		
		NameError
		
		Request - Doc TODO!
			.to_s <=> .to_pem

		RequestError
		
		Revoked
			::new()
			----------------------------------
			serial() => nSerial
			serial=(nSerial) => nSerial
			time() => tRevoked
			time=(tRevoked) => tRevoked
			extensions() => Ary(X509::Extension)
			extensions=(ary) => Ary(X509::Extension)
			add_extension(oExtension) => oExtension

		RevokedError
		
		Store - Doc TODO!

		StoreError
--------------------------------------------------

[Examples]
	There are some braindead in 'test' directory

[Note]
	All code is under development - API/method names can change
	All feedback, bug reports, requests are welcomed!


	Enjoy!

		Michal <m.rokos@sh.cvut.cz>

