diff --git a/.gitignore b/.gitignore index b667100..c216f59 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,9 @@ *.test !*test.go +# Junk for figuring stuff out +/poc/ + # Output of the go coverage tool, specifically when used with LiteIDE *.out diff --git a/README.md b/README.md index 7b72430..be454f4 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,5 @@ OpenSSH key parsing, generation, etc. library for Golang. Supports newer "proprietary" key type formatting ("OpenSSH v1"). + +**WORK IN PROGRESS** diff --git a/_ref/KEY_GUIDE.adoc b/_ref/KEY_GUIDE.adoc index 3c02664..ce7ea6a 100644 --- a/_ref/KEY_GUIDE.adoc +++ b/_ref/KEY_GUIDE.adoc @@ -15,6 +15,12 @@ Last updated {localdatetime} :source-highlighter: rouge :docinfo: shared +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + == Purpose This document attempts to present a much more detailed, thorough, and easily-understood form of the key formats used by OpenSSH. The extent of those formats' canonical documentation is https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key[the OpenSSH source tree's `PROTOCOL.key`^], which is a little lacking. @@ -62,3 +68,15 @@ All public keys in v1 continue to use the same packed binary format as < + Creative Commons License +
+OpenSSH Key Structure Guide by Brent Saner is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
+
+++++ + +You are free to use, distribute, modify, redistribute, use for commercial purposes, etc. with very few restrictions; please see http://creativecommons.org/licenses/by-sa/4.0/[the license summary^] and https://creativecommons.org/licenses/by-sa/4.0/legalcode[full license^] for further details. diff --git a/_ref/KEY_GUIDE.html b/_ref/KEY_GUIDE.html index 962ae87..e0f8311 100644 --- a/_ref/KEY_GUIDE.html +++ b/_ref/KEY_GUIDE.html @@ -4,7 +4,7 @@ - + OpenSSH Key Structure Guide @@ -85,10 +85,10 @@ code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400; ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} ul,ol{margin-left:1.5em} ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0} -ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit} -ul.square{list-style-type:square} ul.circle{list-style-type:circle} ul.disc{list-style-type:disc} +ul.square{list-style-type:square} +ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit} ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} dl dt{margin-bottom:.3125em;font-weight:bold} dl dd{margin-bottom:1.25em} @@ -209,13 +209,10 @@ table.tableblock.fit-content>caption.title{white-space:nowrap;width:0} .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere} .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} .exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px} -.exampleblock>.content>:first-child{margin-top:0} -.exampleblock>.content>:last-child{margin-bottom:0} .sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px} -.sidebarblock>:first-child{margin-top:0} -.sidebarblock>:last-child{margin-bottom:0} .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} -.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} +.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0} +.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} .literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em} @media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}} @media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}} @@ -394,7 +391,7 @@ b.conum *{color:inherit!important} dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility} h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em} p strong,td.content strong,div.footnote strong{letter-spacing:-.005em} -p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem} +p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem} p{margin-bottom:1.25rem} .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} .exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc} @@ -439,217 +436,116 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b @@ -734,7 +630,7 @@ pre.rouge {

OpenSSH Key Structure Guide

brent saner <bts@square-r00t.net>, https://r00t2.io
-Last updated 2022-04-29 16:31:13 -0400 +Last updated 2023-09-04 01:40:40 -0400
Table of Contents
@@ -825,6 +721,7 @@ pre.rouge { +
  • 4. Further Information
  • @@ -2945,6 +2842,19 @@ dCXGDaRlL924VVCYUytRvu7ilZ+dtc9aCQUFJyDF3iXyxN2H68x7teo9e8vqzGtzLkw5KV +
    +

    4. Further Information

    +
    + + Creative Commons License +
    +OpenSSH Key Structure Guide by Brent Saner is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
    +
    +
    +

    You are free to use, distribute, modify, redistribute, use for commercial purposes, etc. with very few restrictions; please see the license summary and full license for further details.

    +
    +
    +

    @@ -2963,7 +2873,7 @@ dCXGDaRlL924VVCYUytRvu7ilZ+dtc9aCQUFJyDF3iXyxN2H68x7teo9e8vqzGtzLkw5KV
    diff --git a/_ref/ed25519/main.adoc b/_ref/ed25519/main.adoc index 5c67b57..0c47c7d 100644 --- a/_ref/ed25519/main.adoc +++ b/_ref/ed25519/main.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + === ED25519 ED25519footnote:[https://datatracker.ietf.org/doc/html/rfc8709] is a relatively somewhat new OpenSSH key algorithm. It has numerous benefits over e.g. RSA, including: diff --git a/_ref/ed25519/private/legacy/main.adoc b/_ref/ed25519/private/legacy/main.adoc index 317d812..78205d5 100644 --- a/_ref/ed25519/private/legacy/main.adoc +++ b/_ref/ed25519/private/legacy/main.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ===== Legacy [NOTE] diff --git a/_ref/ed25519/private/main.adoc b/_ref/ed25519/private/main.adoc index ad18c2a..213b218 100644 --- a/_ref/ed25519/private/main.adoc +++ b/_ref/ed25519/private/main.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ==== Private include::legacy/main.adoc[] diff --git a/_ref/ed25519/private/v1/encrypted.adoc b/_ref/ed25519/private/v1/encrypted.adoc index 533ffde..758ed0c 100644 --- a/_ref/ed25519/private/v1/encrypted.adoc +++ b/_ref/ed25519/private/v1/encrypted.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ===== v1 (Encrypted) [TIP] diff --git a/_ref/ed25519/private/v1/main.adoc b/_ref/ed25519/private/v1/main.adoc index 2483041..9b02e38 100644 --- a/_ref/ed25519/private/v1/main.adoc +++ b/_ref/ed25519/private/v1/main.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + include::plain.adoc[] include::encrypted.adoc[] diff --git a/_ref/ed25519/private/v1/plain.adoc b/_ref/ed25519/private/v1/plain.adoc index eab65a2..5043f15 100644 --- a/_ref/ed25519/private/v1/plain.adoc +++ b/_ref/ed25519/private/v1/plain.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ===== v1 (Plain) [TIP] diff --git a/_ref/ed25519/public.adoc b/_ref/ed25519/public.adoc index 956f7f3..8fdfa7d 100644 --- a/_ref/ed25519/public.adoc +++ b/_ref/ed25519/public.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ==== Public ===== Structure diff --git a/_ref/poc/parse_poc_ed25519.go b/_ref/poc/parse_poc_ed25519.go index 83fbd1a..352973b 100644 --- a/_ref/poc/parse_poc_ed25519.go +++ b/_ref/poc/parse_poc_ed25519.go @@ -1,5 +1,11 @@ package main +/* + * This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. + * To view a copy of this license, visit + * http://creativecommons.org/licenses/by-sa/4.0/. +*/ + import ( "crypto" "crypto/aes" diff --git a/_ref/poc/parse_poc_rsa.go b/_ref/poc/parse_poc_rsa.go index f42f87c..dd0193c 100644 --- a/_ref/poc/parse_poc_rsa.go +++ b/_ref/poc/parse_poc_rsa.go @@ -1,5 +1,11 @@ package main +/* + * This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. + * To view a copy of this license, visit + * http://creativecommons.org/licenses/by-sa/4.0/. +*/ + import ( "crypto/aes" "crypto/cipher" diff --git a/_ref/rsa/main.adoc b/_ref/rsa/main.adoc index 5ccdbd1..ff06469 100644 --- a/_ref/rsa/main.adoc +++ b/_ref/rsa/main.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + === RSA RSAfootnote:[https://datatracker.ietf.org/doc/html/rfc8017] is a widely-supported PKI system. It is ubiquitous, but it is recommended to use newer systems (e.g. ED25519) for OpenSSH if all clients and destinations support it. diff --git a/_ref/rsa/private/legacy/encrypted.adoc b/_ref/rsa/private/legacy/encrypted.adoc index 3f4dd34..0d0228d 100644 --- a/_ref/rsa/private/legacy/encrypted.adoc +++ b/_ref/rsa/private/legacy/encrypted.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ===== Legacy (Encrypted) [id=struct_rsa_crypt_legacy] diff --git a/_ref/rsa/private/legacy/main.adoc b/_ref/rsa/private/legacy/main.adoc index 2483041..9b02e38 100644 --- a/_ref/rsa/private/legacy/main.adoc +++ b/_ref/rsa/private/legacy/main.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + include::plain.adoc[] include::encrypted.adoc[] diff --git a/_ref/rsa/private/legacy/plain.adoc b/_ref/rsa/private/legacy/plain.adoc index 60ee6f0..b66e8e3 100644 --- a/_ref/rsa/private/legacy/plain.adoc +++ b/_ref/rsa/private/legacy/plain.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ===== Legacy (Plain) [id=struct_rsa_plain_legacy] diff --git a/_ref/rsa/private/main.adoc b/_ref/rsa/private/main.adoc index ad18c2a..213b218 100644 --- a/_ref/rsa/private/main.adoc +++ b/_ref/rsa/private/main.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ==== Private include::legacy/main.adoc[] diff --git a/_ref/rsa/private/v1/encrypted.adoc b/_ref/rsa/private/v1/encrypted.adoc index fb26e8e..f13812f 100644 --- a/_ref/rsa/private/v1/encrypted.adoc +++ b/_ref/rsa/private/v1/encrypted.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ===== v1 (Encrypted) [TIP] diff --git a/_ref/rsa/private/v1/main.adoc b/_ref/rsa/private/v1/main.adoc index 2483041..9b02e38 100644 --- a/_ref/rsa/private/v1/main.adoc +++ b/_ref/rsa/private/v1/main.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + include::plain.adoc[] include::encrypted.adoc[] diff --git a/_ref/rsa/private/v1/plain.adoc b/_ref/rsa/private/v1/plain.adoc index 4a42593..884d286 100644 --- a/_ref/rsa/private/v1/plain.adoc +++ b/_ref/rsa/private/v1/plain.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ===== v1 (Plain) [TIP] diff --git a/_ref/rsa/public.adoc b/_ref/rsa/public.adoc index 34c9fc8..65fc5e9 100644 --- a/_ref/rsa/public.adoc +++ b/_ref/rsa/public.adoc @@ -1,3 +1,9 @@ +//// +This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. +To view a copy of this license, visit +http://creativecommons.org/licenses/by-sa/4.0/. +//// + ==== Public ===== Structure diff --git a/_ref/sources b/_ref/sources index bef4aac..b1d6cc8 100644 --- a/_ref/sources +++ b/_ref/sources @@ -1,3 +1,13 @@ +###################################################################################################### +# This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. # +# To view a copy of this license, visit # +# http://creativecommons.org/licenses/by-sa/4.0/. # +###################################################################################################### + += NOTES = + +This document is largely just a dump of "further reading" resources. + https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key canonical: https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD https://peterlyons.com/problog/2017/12/openssh-ed25519-private-key-file-format/ @@ -48,4 +58,4 @@ https://github.com/openssh/openssh-portable/blob/master/authfile.c sshkey_save_private_blob (~L56) https://github.com/openssh/openssh-portable/blob/master/ssh-keygen.c funcs: - main (~L3145; ~L3673 onwards for key generation) \ No newline at end of file + main (~L3145; ~L3673 onwards for key generation) diff --git a/cipher/aes/aes128/gcm/TODO b/cipher/aes/aes128/gcm/TODO new file mode 100644 index 0000000..d23aeb2 --- /dev/null +++ b/cipher/aes/aes128/gcm/TODO @@ -0,0 +1,3 @@ +TODO + +I need to look further into the aes128-gcm@openssh.com variant to see if this is valid. diff --git a/cipher/aes/aes256/gcm/TODO b/cipher/aes/aes256/gcm/TODO new file mode 100644 index 0000000..31d5f3c --- /dev/null +++ b/cipher/aes/aes256/gcm/TODO @@ -0,0 +1,3 @@ +TODO + +I need to look further into the aes256-gcm@openssh.com variant to see if this is valid. diff --git a/cipher/chacha20/poly1305/TODO b/cipher/chacha20/poly1305/TODO index 1333ed7..9e56496 100644 --- a/cipher/chacha20/poly1305/TODO +++ b/cipher/chacha20/poly1305/TODO @@ -1 +1,14 @@ TODO + +I need to fork out the chacha20-poly1305 pkg from golang x-stdlib +( + https://pkg.go.dev/golang.org/x/crypto/chacha20poly1305 + https://cs.opensource.google/go/x/crypto/+/master:chacha20poly1305/ + https://github.com/golang/go/issues/36646 +) +because they explicitly do NOT support the chacha20-poly1305 OpenSSH variant (chacha20-poly1305@openssh.com) +(https://github.com/golang/go/issues/36646#issue-552055939 +"and there is exactly one widely used (or otherwise) composition: + ChaCha20Poly1305 as implemented by x/crypto/chacha20poly1305 (or by SSH in their weird variant)" + +sidenote, this is the same guy that decided it would be a good idea to deprecate golang x-stdlib gpg). diff --git a/cipher/chacha20/poly1305/consts.go b/cipher/chacha20/poly1305/consts.go index eb005c6..f7d8ef9 100644 --- a/cipher/chacha20/poly1305/consts.go +++ b/cipher/chacha20/poly1305/consts.go @@ -1,5 +1,6 @@ package poly1305 const ( - Name string = "chacha20-poly1305@openssh.com" + Name string = "chacha20-poly1305@openssh.com" + BlockSize int = 8 ) diff --git a/cipher/chacha20/poly1305/funcs.go b/cipher/chacha20/poly1305/funcs.go index 635cba8..3a78398 100644 --- a/cipher/chacha20/poly1305/funcs.go +++ b/cipher/chacha20/poly1305/funcs.go @@ -4,8 +4,7 @@ import ( `bytes` `io` - `r00t2.io/sshkeys/cipher/aes` - `r00t2.io/sshkeys/cipher/aes/aes128` + `r00t2.io/cc20p1305ssh` `r00t2.io/sshkeys/internal` ) @@ -39,7 +38,7 @@ func (c *Cipher) NameBytes() (name []byte) { // BlockSize returns the blocksize of this Cipher. func (c *Cipher) BlockSize() (size int) { - size = aes.BlockSize + size = BlockSize return } @@ -47,7 +46,7 @@ func (c *Cipher) BlockSize() (size int) { // KdfKeySize returns the target key length from KDF to use with this Cipher. func (c *Cipher) KdfKeySize() (size int) { - size = aes128.KeySize + size = cc20p1305ssh.KeySize return } diff --git a/cipher/chacha20/poly1305/types.go b/cipher/chacha20/poly1305/types.go index 3f38089..e2d7351 100644 --- a/cipher/chacha20/poly1305/types.go +++ b/cipher/chacha20/poly1305/types.go @@ -1,5 +1,22 @@ package poly1305 +/* + Cipher is a ChaCha20-Poly1305 (OpenSSH variant) cipher.Cipher. + + In the OpenSSH variant (for *key* encryption), only the first + 32 bytes is used from the 64-byte key as generated from ChaCha20. + + It then proceeds per https://datatracker.ietf.org/doc/html/rfc8439#section-2.8 + except: + + * The nonce used is a constant of 16 zero bytes + * There is no additional authenticated data + * The Poly1305 authentication tag is generated via a message + that consists *only* of the ciphertext. + In other words, OpenSSH does *not* add padding or + encode message lengths to generate the Poly1305 + authentication tag. +*/ type Cipher struct { Key []byte } diff --git a/cipher/null/consts.go b/cipher/null/consts.go new file mode 100644 index 0000000..6b94fe9 --- /dev/null +++ b/cipher/null/consts.go @@ -0,0 +1,6 @@ +package null + +const ( + Name string = "" + BlockSize int = 8 +) diff --git a/cipher/null/funcs.go b/cipher/null/funcs.go index 3026825..67ebe89 100644 --- a/cipher/null/funcs.go +++ b/cipher/null/funcs.go @@ -1,17 +1,26 @@ package null import ( - `bytes` - `io` + "bytes" - `r00t2.io/sshkeys/cipher/aes` - `r00t2.io/sshkeys/cipher/aes/aes128` - `r00t2.io/sshkeys/internal` + `r00t2.io/sshkeys/cipher` + "r00t2.io/sshkeys/internal" ) +/* + Setup populates a Cipher from a key. + + This is basically a no-op as null.Cipher does not offer any encryption, so there's no setup necessary. +*/ func (c *Cipher) Setup(key []byte) (err error) { - // TODO + if c == nil { + *c = Cipher{} + } + + if err = c.keyChk(); err != nil { + return + } return } @@ -39,21 +48,26 @@ func (c *Cipher) NameBytes() (name []byte) { // BlockSize returns the blocksize of this Cipher. func (c *Cipher) BlockSize() (size int) { - size = aes.BlockSize - - return -} - -// KdfKeySize returns the target key length from KDF to use with this Cipher. -func (c *Cipher) KdfKeySize() (size int) { - - size = aes128.KeySize + size = BlockSize return } /* - Encrypt encrypts data (a string, []byte, byte, *bytes.Buffer, or *bytes.Reader) to the *bytes.Reader encrypted. + KdfKeySize returns the target key length from KDF to use with this Cipher. + + Because this function is only here for interface compat, it always returns 0 + (as a Null cipher uses no KDF). +*/ +func (c *Cipher) KdfKeySize() (size int) { + + size = 0 + + return +} + +/* + Encrypt "encrypts" data (a string, []byte, byte, *bytes.Buffer, or *bytes.Reader) to the *bytes.Reader encrypted. NOTE: Padding IS applied automatically. @@ -61,31 +75,15 @@ func (c *Cipher) KdfKeySize() (size int) { It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Encrypt. NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. + + NOTE: No actual encryption takes place, only padding. */ func (c *Cipher) Encrypt(data interface{}) (encrypted *bytes.Reader, err error) { - var b []byte - var cryptDst []byte - var padded *bytes.Reader - - if b, err = internal.SerializeData(data); err != nil { + if encrypted, err = c.Pad(data); err != nil { return } - if padded, err = c.Pad(b); err != nil { - return - } - - b = make([]byte, padded.Len()) - if b, err = io.ReadAll(padded); err != nil { - return - } - - cryptDst = make([]byte, len(b)) - - // TODO - _ = cryptDst - return } @@ -125,17 +123,38 @@ func (c *Cipher) AllocateEncrypt(data interface{}) (encrypted *bytes.Reader, err } /* - Pad will pad data (a string, []byte, byte, or *bytes.Buffer) to the Cipher.BlockSize (if necessary). - The resulting padded buffer is returned. + Pad will pad data (a string, []byte, byte, *bytes.Buffer, *bytes.Reader) to the Cipher.BlockSize. The resulting padded *bytes.Reader is returned. NOTE: If data is a *bytes.Buffer, no bytes will be consumed -- the bytes are taken in entirety without consuming them (Buffer.Bytes()). - It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Cipher.Pad. + It is up to the caller to consume the buffer as desired beforehand or isolate to a specific sub-buffer beforehand to pass to Pad. NOTE: If data is a *bytes.Reader, ALL bytes WILL be consumed. */ func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { - // TODO + var b []byte + var padNum int + var pad []byte + var buf *bytes.Buffer + + if err = c.keyChk(); err != nil { + return + } + + if b, err = internal.UnpackBytes(data); err != nil { + return + } + buf = bytes.NewBuffer(b) + + for padIdx := 1; (buf.Len() % BlockSize) != 0; padIdx++ { + + padNum = padIdx & cipher.PadMod + pad = []byte{byte(uint32(padNum))} + + if _, err = buf.Write(pad); err != nil { + return + } + } return } @@ -152,17 +171,13 @@ func (c *Cipher) Pad(data interface{}) (paddedBuf *bytes.Reader, err error) { */ func (c *Cipher) Decrypt(data interface{}) (decrypted *bytes.Reader, err error) { - var b []byte - var decryptDst []byte + var plain []byte - if b, err = internal.SerializeData(data); err != nil { + if plain, err = internal.SerializeData(data); err != nil { return } - decryptDst = make([]byte, len(b)) - - // TODO - _ = decryptDst + decrypted = bytes.NewReader(plain) return } @@ -195,11 +210,21 @@ func (c *Cipher) AllocatedDecrypt(data interface{}) (decrypted *bytes.Reader, er /* IsPlain indicates if this Cipher is a plain/null encryption (cipher.null.Null). - It will always return false. It is included for interface compatability. + It will always return true. It is included for interface compatability. */ func (c *Cipher) IsPlain() (plain bool) { - plain = false + plain = true + + return +} + +// keyChk is more or less a no-op but provides some basic sanity checking. +func (c *Cipher) keyChk() (err error) { + + if c == nil { + *c = Cipher{} + } return } diff --git a/cipher/null/types.go b/cipher/null/types.go new file mode 100644 index 0000000..f26449c --- /dev/null +++ b/cipher/null/types.go @@ -0,0 +1,4 @@ +package null + +// Cipher is a null (plaintext) cipher.Cipher. +type Cipher struct{}