Commit Graph

49 Commits

Author SHA1 Message Date
David Benjamin
d81e73dcbb Factor out sequence number updates.
Also check for overflow, although it really shouldn't happen.

Change-Id: I34dfe8eaf635aeaa8bef2656fda3cd0bad7e1268
Reviewed-on: https://boringssl-review.googlesource.com/4235
Reviewed-by: Adam Langley <agl@google.com>
2015-04-06 20:50:37 +00:00
David Benjamin
cfd248b7f6 Clean up SSL_export_keying_material implementation.
Fix up the variable names. Also avoid the messy logic of checking whether the
label and context collide with the normal key expansion ones in the face of
adverserial inputs. Make that the caller's responsibility, just as it's already
the caller's responsibility to ensure that different calls don't overlap.  (The
label should be a constant string in an IANA registry anyway.)

Change-Id: I062fadb7b6a18fa946b883be660ea9b3f0f6277c
Reviewed-on: https://boringssl-review.googlesource.com/4216
Reviewed-by: Adam Langley <agl@google.com>
2015-04-06 20:47:54 +00:00
David Benjamin
b34f510b3b Don't delay-initialize legacy AEADs.
Instead, add a separate init_with_direction hook. Normal AEADs ignore the
direction, while legacy AEADs must be initialized with it. This avoids
maintaining extra state to support the delayed initialization.

Change-Id: I25271f0e56ee2783a2fd4d4026434154d58dc0a8
Reviewed-on: https://boringssl-review.googlesource.com/3731
Reviewed-by: Adam Langley <agl@google.com>
2015-03-05 21:25:05 +00:00
David Benjamin
9d0847ae6d Add some missing error failure checks.
Found while diagnosing some crashes and hangs in the malloc tests. This (and
the follow-up) get us further but does not quite let the malloc tests pass
quietly, even without valgrind. DTLS silently ignores some malloc failures
(confusion with silently dropping bad packets) which then translate to hangs.

Change-Id: Ief06a671e0973d09d2883432b89a86259e346653
Reviewed-on: https://boringssl-review.googlesource.com/3482
Reviewed-by: Adam Langley <agl@google.com>
2015-02-17 20:55:56 +00:00
David Benjamin
afbc63fc2f Simplify DTLS epoch rewind.
SSL_AEAD_CTX ownership is currently too confusing. Instead, rely on the lack of
renego, so the previous epoch always uses the NULL cipher. (Were we to support
DTLS renego, we could keep track of s->d1->last_aead_write_ctx like
s->d1->last_write_sequence, but it isn't worth it.)

Buffered messages also tracked an old s->session, but this is unnecessary. The
s->session NULL check in tls1_enc dates to the OpenSSL initial commit and is
redundant with the aead NULL check.

Change-Id: I9a510468d95934c65bca4979094551c7536980ae
Reviewed-on: https://boringssl-review.googlesource.com/3234
Reviewed-by: Adam Langley <agl@google.com>
2015-02-03 20:34:06 +00:00
David Benjamin
1e52ecac4d Normalize tls1_enc return values.
The distinction between publicly and non-publicly invalid is barely acted upon
and slightly silly now that the CBC padding check has been folded into
EVP_AEAD.

Change-Id: Idce4b9b8d29d624e3c95243a147265d071612127
Reviewed-on: https://boringssl-review.googlesource.com/2980
Reviewed-by: Adam Langley <agl@google.com>
2015-01-22 22:00:01 +00:00
David Benjamin
b8a56f112f Remove dead code from EVP_CIPHER codepaths.
Everything is an AEAD now.

Change-Id: Ib47638e128843fc8299c3dbf9bd60c01eb5afa16
Reviewed-on: https://boringssl-review.googlesource.com/2700
Reviewed-by: Adam Langley <agl@google.com>
2015-01-14 21:05:41 +00:00
David Benjamin
e95d20dcb8 Support EVP_AEAD in DTLS.
This CL removes the last of the EVP_CIPHER codepath in ssl/. The dead code is
intentionally not pruned for ease of review, except in DTLS-only code where
adding new logic to support both, only to remove half, would be cumbersome.

Fixes made:
- dtls1_retransmit_state is taught to retain aead_write_ctx rather than
  enc_write_ctx.
- d1_pkt.c reserves space for the variable-length nonce when echoed into the
  packet.
- dtls1_do_write sizes the MTU based on EVP_AEAD max overhead.
- tls1_change_cipher_state_cipher should not free AEAD write contexts in DTLS.
  This matches the (rather confused) ownership for the EVP_CIPHER contexts.
  I've added a TODO to resolve this craziness.

A follow-up CL will remove all the resultant dead code.

Change-Id: I644557f4db53bbfb182950823ab96d5e4c908866
Reviewed-on: https://boringssl-review.googlesource.com/2699
Reviewed-by: Adam Langley <agl@google.com>
2015-01-14 21:03:40 +00:00
David Benjamin
044abb0aaa Implement SSLv3 ciphers with stateful AEADs.
This introduces another knob into SSL_AEAD_CTX to omit the version from the ad
parameter. It also allows us to fold a few more SSL3_ENC_METHOD hooks together.

Change-Id: I6540d410d4722f734093554fb434dab6e5217d4f
Reviewed-on: https://boringssl-review.googlesource.com/2698
Reviewed-by: Adam Langley <agl@google.com>
2015-01-14 20:55:58 +00:00
David Benjamin
41ac979211 Add the PRF to SSL3_ENC_METHOD.
This lets us fold away the SSLv3-specific generate_master_secret. Once SSLv3
uses AEADs, others will fold away as well.

Change-Id: I27c1b75741823bc6db920d35f5dd5ce71b6fdbb3
Reviewed-on: https://boringssl-review.googlesource.com/2697
Reviewed-by: Adam Langley <agl@google.com>
2015-01-14 20:43:26 +00:00
David Benjamin
31b1d81354 Factor SSLv3 key derivation steps into an ssl3_PRF.
Fix up the generate_master_secret parameter while we're here.

Change-Id: I1c80796d1f481be0c3eefcf3222f2d9fc1de4a51
Reviewed-on: https://boringssl-review.googlesource.com/2696
Reviewed-by: Adam Langley <agl@google.com>
2015-01-14 20:43:08 +00:00
David Benjamin
1f5e115ea9 Tidy up tls1_PRF a little.
size_t all the parameters. Also explicitly label label as label. This is in
preparation for pulling the PRF out into SSL3_ENC_METHOD so more of the
SSL3_ENC_METHOD hooks may be shared between SSLv3 and TLS once SSLv3 uses
stateful AEADs.

Also port away from EVP_PKEY_HMAC and use HMAC_CTX directly. The abstraction
doesn't buy much and is different from all the other EVP_DigestSign* functions.
There are few enough users within BoringSSL and Google that we can probably
deprecate and eventually remove it altogether.

Change-Id: I5d4529438c8a2a992fc199388a0c9e73bd6d2e06
Reviewed-on: https://boringssl-review.googlesource.com/2695
Reviewed-by: Adam Langley <agl@google.com>
2015-01-14 20:42:33 +00:00
David Benjamin
ea72bd0b60 Implement all TLS ciphers with stateful AEADs.
The EVP_CIPHER codepath should no longer be used with TLS. It still exists for
DTLS and SSLv3. The AEAD construction in TLS does not allow for
variable-overhead AEADs, so stateful AEADs do not include the length in the ad
parameter. Rather the AEADs internally append the unpadded length once it is
known. EVP_aead_rc4_md5_tls is modified to account for this.

Tests are added (and RC4-MD5's regenerated) for each of the new AEADs. The
cipher tests are all moved into crypto/cipher/test because there's now a lot of
them and they clutter the directory listing.

In ssl/, the stateful AEAD logic is also modified to account for stateful AEADs
with a fixed IV component, and for AEADs which use a random nonce (for the
explicit-IV CBC mode ciphers).

The new implementation fixes a bug/quirk in stateless CBC mode ciphers where
the fixed IV portion of the keyblock was generated regardless. This is at the
end, so it's only relevant for EAP-TLS which generates a MSK from the end of
the key block.

Change-Id: I2d8b8aa11deb43bde2fd733f4f90b5d5b8cb1334
Reviewed-on: https://boringssl-review.googlesource.com/2692
Reviewed-by: Adam Langley <agl@google.com>
2015-01-14 20:30:26 +00:00
David Benjamin
af032d68b3 Allocate the temporary buffer in tls1_PRF internally.
It's not worth saving the extra mallocs. This is preparation for moving SSLv3
to stateful AEADs; it'll share code TLS's SSL3_ENC_METHOD, but
tls1_generate_key_block is different, so that'll be pulled out into its own
hook.

Change-Id: I3f2136600758465c66ce23736041bb47f74efa6d
Reviewed-on: https://boringssl-review.googlesource.com/2690
Reviewed-by: Adam Langley <agl@google.com>
2015-01-14 19:47:45 +00:00
Adam Langley
fcf25833bc Reformat the rest of ssl/.
Change-Id: I7dc264f7e29b3ba8be4c717583467edf71bf8dd9
2014-12-18 17:43:03 -08:00
David Benjamin
a6d81018f8 Consistently use RAND_bytes and check for failure.
RAND_pseudo_bytes just calls RAND_bytes now and only returns 0 or 1. Switch all
callers within the library call the new one and use the simpler failure check.
This fixes a few error checks that no longer work (< 0) and some missing ones.

Change-Id: Id51c79deec80075949f73fa1fbd7b76aac5570c6
Reviewed-on: https://boringssl-review.googlesource.com/2621
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 19:15:59 +00:00
David Benjamin
4841ce49a0 Fix EVP_Cipher error-handling.
Turns out the EVP_CIPH_FLAG_CUSTOM_CIPHER ciphers (i.e. legacy EVP_CIPHER
AES-GCM) have a completely different return value setup than the normal ones
which are the standard one/zero. (Except that they never return zero; see
TODO.)

Fix checks in ssl/ and remove remnants of EVP_CIPH_FLAG_CUSTOM_CIPHER in ssl/
as we're using EVP_AEAD now.

See CHANGES entry added in upstream's 3da0ca796cae6625bd26418afe0a1dc47bf5a77f.

Change-Id: Ia4d0ff59b03c35fab3a08141c60b9534cb7172e2
Reviewed-on: https://boringssl-review.googlesource.com/2606
Reviewed-by: Adam Langley <agl@google.com>
2014-12-16 01:51:55 +00:00
David Benjamin
82c9e90a58 Merge SSLv23_method and DTLS_ANY_VERSION.
This makes SSLv23_method go through DTLS_ANY_VERSION's version negotiation
logic. This allows us to get rid of duplicate ClientHello logic. For
compatibility, SSL_METHOD is now split into SSL_PROTOCOL_METHOD and a version.
The legacy version-locked methods set min_version and max_version based this
version field to emulate the original semantics.

As a bonus, we can now handle fragmented ClientHello versions now.

Because SSLv23_method is a silly name, deprecate that too and introduce
TLS_method.

Change-Id: I8b3df2b427ae34c44ecf972f466ad64dc3dbb171
2014-12-13 15:22:21 -08:00
Adam Langley
69a01608f3 Add malloc failure tests.
This commit fixes a number of crashes caused by malloc failures. They
were found using the -malloc-test=0 option to runner.go which runs tests
many times, causing a different allocation call to fail in each case.

(This test only works on Linux and only looks for crashes caused by
allocation failures, not memory leaks or other errors.)

This is not the complete set of crashes! More can be found by collecting
core dumps from running with -malloc-test=0.

Change-Id: Ia61d19f51e373bccb7bc604642c51e043a74bd83
Reviewed-on: https://boringssl-review.googlesource.com/2320
Reviewed-by: Adam Langley <agl@google.com>
2014-11-19 01:24:46 +00:00
Adam Langley
0e2a3cf98a Remove KSSL_DEBUG.
As far as I know, this is scar tissue left over from a Solaris feature:
http://www.c0t0d0s0.org/archives/5575-Less-known-Solaris-Features-kssl.html

Change-Id: I9fdc21de225f15d29bf856174bcd42e2592f8d95
Reviewed-on: https://boringssl-review.googlesource.com/2141
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2014-11-04 19:35:38 +00:00
David Benjamin
a0ca1b742f DTLS1_AD_MISSING_HANDSHAKE_MESSAGE does not exist.
This code isn't compiled in. It seems there was some half-baked logic for a
7-byte alert that includes more information about handshake messages
retransmit.

No such alert exists, and the code had a FIXME anyway. If it gets resurrected
in DTLS 1.3 or some extension, we can deal with it then.

Change-Id: I8784ea8ee44bb8da4b0fe5d5d507997526557432
Reviewed-on: https://boringssl-review.googlesource.com/2121
Reviewed-by: Adam Langley <agl@google.com>
2014-11-04 00:26:01 +00:00
Adam Langley
7571292eac Extended master secret support.
This change implements support for the extended master secret. See
https://tools.ietf.org/html/draft-ietf-tls-session-hash-01
https://secure-resumption.com/

Change-Id: Ifc7327763149ab0894b4f1d48cdc35e0f1093b93
Reviewed-on: https://boringssl-review.googlesource.com/1930
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2014-10-24 21:19:44 +00:00
David Benjamin
d7a76e72c6 Remove key_arg and key_arg_length from SSL_SESSION.
Remnants of SSLv2 support.

Change-Id: If45035f1727f235e122121418770f75257b18026
Reviewed-on: https://boringssl-review.googlesource.com/1991
Reviewed-by: Adam Langley <agl@google.com>
2014-10-21 17:55:49 +00:00
Adam Langley
88333ef7d7 Fix switching between AEAD and non-AEAD in a renegotiation.
https://code.google.com/p/chromium/issues/detail?id=423998

Change-Id: I29d67db92b47d6cd303125b44e5ba552d97d54ff
Reviewed-on: https://boringssl-review.googlesource.com/1960
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2014-10-20 19:05:23 +00:00
David Benjamin
fb3ff2c66c Don't compare signed vs. unsigned.
This resolves a pile of MSVC warnings in Chromium.

Change-Id: Ib9a29cb88d8ed8ec4118d153260f775be059a803
Reviewed-on: https://boringssl-review.googlesource.com/1865
Reviewed-by: Adam Langley <agl@google.com>
2014-10-01 02:17:38 +00:00
David Benjamin
d633d6303c Remove indirection in loading ciphers.
Simplify all the cipher gathering logic. The set of supported ciphers is known,
so there is no need to determine if some cipher exists but doesn't work.

Change-Id: Idcaae67e7bfc40a3deb925d85ee1a99a931b67e7
Reviewed-on: https://boringssl-review.googlesource.com/1756
Reviewed-by: Adam Langley <agl@google.com>
2014-09-15 21:06:10 +00:00
David Benjamin
c92c2d7a07 Prune some dead quirks and document the SSL_OP_ALL ones.
Update SSL_OP_ALL to account for SSL_OP_CRYPTOPRO_TLSEXT_BUG being gone,
and update ssl3_setup_write_buffer to account for SSL_MODE_CBC_RECORD_SPLITTING
rather than the now defunct SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.

Also remove SSL_OP_TLS_BLOCK_PADDING_BUG. This is to allow for a buggy peer
which pads CBC with N bytes of value N rather than N+1 bytes of value N. This
quirk has been broken since CBC padding checks became constant-time, as
demonstrated by this attempt at a test. (Instead of just decrementing
padding_length, it needs to also keep track of a separate padding_value and not
decrement that one.)

https://boringssl-review.googlesource.com/#/c/1690/

(The quirk would also fall over anyway if the buggy client ever did a session
resumption; then the server speaks first rather than the client, and the quirk
triggered on reading the first encrypted record from the peer.)

Change-Id: I19942dc629a47832aead77a46bb50e0b0a9780b3
Reviewed-on: https://boringssl-review.googlesource.com/1694
Reviewed-by: Adam Langley <agl@google.com>
2014-09-03 20:17:45 +00:00
David Benjamin
f0fd37323b Remove remnants of EVP_CIPHER-based AES_GCM cipher.
Those codepaths are never hit.

Change-Id: Ib6908ebe90ab667774785298fdc3f96acc4b50df
Reviewed-on: https://boringssl-review.googlesource.com/1693
Reviewed-by: Adam Langley <agl@google.com>
2014-09-02 22:42:26 +00:00
David Benjamin
457112e197 unifdef a bunch of OPENSSL_NO_* ifdefs.
Get all this stuff out of the way.

- OPENSSL_NO_MD5
- OPENSSL_NO_SHA
- OPENSSL_NO_EC
- OPENSSL_NO_ECDSA
- OPENSSL_NO_ECDH
- OPENSSL_NO_NEXTPROTONEG
- OPENSSL_NO_DH
- OPENSSL_NO_SSL3
- OPENSSL_NO_RC4
- OPENSSL_NO_RSA

Also manually removed a couple instances of OPENSSL_NO_DSA that seemed to be
confused anyway. Did some minor manual cleanup. (Removed a few now-pointless
'if (0)'s.)

Change-Id: Id540ba97ee22ff2309ab20ceb24c7eabe766d4c4
Reviewed-on: https://boringssl-review.googlesource.com/1662
Reviewed-by: Adam Langley <agl@google.com>
2014-08-28 00:41:34 +00:00
David Benjamin
f9b96fa493 Fix flipped DTLS checks.
09bd58d1f1 flipped a condition. Doing that
memset in the DTLS case breaks retransmits across a CCS and fails to memset in
the TLS case.

Strangely, it didn't break any tests, but I think that's a function of us
lacking renego tests. The sequence number doesn't seem to be used in the
initial handshake for TLS, so it stayed at zero. After a renego, that codepath
is relevant.

Change-Id: I369a524021857a82e181af7798c7a10fe6279550
Reviewed-on: https://boringssl-review.googlesource.com/1601
Reviewed-by: Adam Langley <agl@google.com>
2014-08-25 21:49:36 +00:00
David Benjamin
ebf42b5f6f Remove remnants of now-removed cipher suites.
NULL, SRP, CAMELLIA, export ciphers, SSLv2, IDEA, and SEED are gone. Unknown
directives are silently ignored in the parser, so there is no need to retain
their masks and entries in the cipher suite aliases.

Change-Id: If43b9cbce56b3e1c401db764b88996940452a300
Reviewed-on: https://boringssl-review.googlesource.com/1561
Reviewed-by: Adam Langley <agl@google.com>
2014-08-20 02:02:17 +00:00
David Benjamin
09bd58d1f1 Replace some DTLS version checks with SSL_IS_DTLS.
They weren't updated to account for DTLS 1.2.

Change-Id: I81b3bfcb84a46d7b233bb567976a7de37bc46b92
Reviewed-on: https://boringssl-review.googlesource.com/1503
Reviewed-by: Adam Langley <agl@google.com>
2014-08-13 21:58:03 +00:00
David Benjamin
060d9d2c56 Remove support code for export cipher suites.
Now the only case where temporary RSA keys are used on the server end is
non-signing keys.

Change-Id: I55f6c206e798dd28548c386fdffd555ccc395477
Reviewed-on: https://boringssl-review.googlesource.com/1285
Reviewed-by: Adam Langley <agl@google.com>
2014-07-24 21:14:08 +00:00
David Benjamin
019c3cc64a Remove last remnants of GOST support.
This removes support code for a "stream_mac" mode only used by GOST. Also get
rid of this

   /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */

comment next to it. It's not actually related to GOST (dates to OpenSSL initial
commit), but isn't especially helpful at this point.

Change-Id: Ib13c6e27e16e0d1fb59ed0142ddf913b9abc20b7
Reviewed-on: https://boringssl-review.googlesource.com/1281
Reviewed-by: Adam Langley <agl@google.com>
2014-07-24 21:10:53 +00:00
David Benjamin
7bf334a9ff Perform bounds checks in hmac_signctx.
Match the other EVP_DigestSignFinal implementations. Fix the instances in
ssl/t1_enc.c which were not following the EVP_DigestSignFinal contract; on
entry, *out_len should contain the size of the buffer.

Change-Id: Icd44d97a4c98704dea975798c0101d5a37274d17
Reviewed-on: https://boringssl-review.googlesource.com/1130
Reviewed-by: Adam Langley <agl@google.com>
2014-07-10 20:59:10 +00:00
David Benjamin
64f4c91b89 Remove OPENSSL_FIPS blocks.
Done with unifdef with some manual edits to remove empty lines.

Change-Id: I40d163539cab8ef0e01e45b7dc6a1a0a37733c3e
Reviewed-on: https://boringssl-review.googlesource.com/1097
Reviewed-by: Adam Langley <agl@google.com>
2014-07-07 20:31:50 +00:00
David Benjamin
fd76191821 Remove opaque_prf_input extension.
This code doesn't even get built unless you go out of your way to pass an
extension value at build time.

Change-Id: I92ffcdfb18505c96e5ef390c8954a54cee19967f
Reviewed-on: https://boringssl-review.googlesource.com/1063
Reviewed-by: Adam Langley <agl@google.com>
2014-07-01 18:55:19 +00:00
Adam Langley
9447dff5a2 Use RC4-MD5 AEAD in ssl/
This change adds the infrastructure to use stateful AEADs in ssl/ and
specifically wires in the stitched, RC4-MD5 AEAD. Over time, all
cipher suites will be supported via the AEAD interface and the old
EVP_CIPHER code will die off.

Change-Id: I44ed3ca2672e1342c6b632be08fee9272d113f8e
Reviewed-on: https://boringssl-review.googlesource.com/1044
Reviewed-by: Adam Langley <agl@google.com>
2014-06-30 23:39:17 +00:00
Victor Vasiliev
508c29fec9 Remove references to AEAD in non-AEAD interface codepath
Since all AEAD ciphers now go through EVP_AEAD interface, the code which
uses EVP_Cipher interface no longer needs any of AEAD handling logic.

This also removes EVP_CTRL_AEAD_TLS1_AAD from GCM interface, which was
duplicating non-TLS-specific GCM logic and is not used anymore.

Change-Id: I5ddae880e7bc921337f9149a0acfdd00c9a478c3
2014-06-25 15:56:05 -04:00
David Benjamin
95463b311d Remove crypto/comp and SSL_COMP support code.
Now that the consuming code in ssl/ is removed, there is no need for this.
Leave SSL_COMP and STACK_OF(SSL_COMP) for now so as not to break any code which
manipulates the output of SSL_COMP_get_compression_methods to disable
compression.

Change-Id: Idf0a5debd96589ef6e7e56acf5d9259412b7d7a1
2014-06-24 17:22:06 +00:00
Adam Langley
caddf1c4de Use correct digest when exporting keying material.
PR#3319

(Imported from upstream's 87a0cbdf2ee539ea922f9cf7a4b7c2c03119891d)
2014-06-20 13:17:40 -07:00
Adam Langley
9f61d7f4a1 ssl/t1_enc.c: check EVP_MD_CTX_copy return value.
PR: 3201

(Imported from upstream's 8d08627c940900998d02a0dff0566db736efb94f)
2014-06-20 13:17:38 -07:00
Adam Langley
2970779684 Fallback SCSV.
This patch adds server-side support for TLS_FALLBACK_SCSV (see
http://tools.ietf.org/html/draft-bmoeller-tls-downgrade-scsv-01).
2014-06-20 13:17:36 -07:00
Adam Langley
d493d5289d CBC record splitting.
This patch removes support for empty records (which is almost
universally disabled via SSL_OP_ALL) and adds optional support for 1/n-1
record splitting.

The latter is not enabled by default, since it's not typically used on
servers, but it should be enabled in web browsers since there are known
attacks in that case (see BEAST).
2014-06-20 13:17:35 -07:00
Adam Langley
de0b202684 ChaCha20-Poly1305 support. 2014-06-20 13:17:35 -07:00
Adam Langley
c9fb37504f SSL AEAD support.
This change allows AEADs to be used in ssl/ to implement SSL/TLS
ciphersuites.
2014-06-20 13:17:34 -07:00
Adam Langley
a5fa5b7bb6 tls1_change_cipher_state rewrite
The previous version of the function made adding AEAD changes very
difficult. This change should be a semantic no-op - it should be purely
a cleanup.
2014-06-20 13:17:34 -07:00
Adam Langley
1258b6a756 ChannelID support.
Implement ChannelID as both a client and server.
2014-06-20 13:17:33 -07:00
Adam Langley
95c29f3cd1 Inital import.
Initial fork from f2d678e6e89b6508147086610e985d4e8416e867 (1.0.2 beta).

(This change contains substantial changes from the original and
effectively starts a new history.)
2014-06-20 13:17:32 -07:00