mirror of
https://github.com/rclone/rclone.git
synced 2024-12-21 11:06:55 +08:00
64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
|
// Package pkcs7 implements PKCS#7 padding
|
||
|
//
|
||
|
// This is a standard way of encoding variable length buffers into
|
||
|
// buffers which are a multiple of an underlying crypto block size.
|
||
|
package pkcs7
|
||
|
|
||
|
import "github.com/pkg/errors"
|
||
|
|
||
|
// Errors Unpad can return
|
||
|
var (
|
||
|
ErrorPaddingNotFound = errors.New("Bad PKCS#7 padding - not padded")
|
||
|
ErrorPaddingNotAMultiple = errors.New("Bad PKCS#7 padding - not a multiple of blocksize")
|
||
|
ErrorPaddingTooLong = errors.New("Bad PKCS#7 padding - too long")
|
||
|
ErrorPaddingTooShort = errors.New("Bad PKCS#7 padding - too short")
|
||
|
ErrorPaddingNotAllTheSame = errors.New("Bad PKCS#7 padding - not all the same")
|
||
|
)
|
||
|
|
||
|
// Pad buf using PKCS#7 to a multiple of n.
|
||
|
//
|
||
|
// Appends the padding to buf - make a copy of it first if you don't
|
||
|
// want it modified.
|
||
|
func Pad(n int, buf []byte) []byte {
|
||
|
if n <= 1 || n >= 256 {
|
||
|
panic("bad multiple")
|
||
|
}
|
||
|
length := len(buf)
|
||
|
padding := n - (length % n)
|
||
|
for i := 0; i < padding; i++ {
|
||
|
buf = append(buf, byte(padding))
|
||
|
}
|
||
|
if (len(buf) % n) != 0 {
|
||
|
panic("padding failed")
|
||
|
}
|
||
|
return buf
|
||
|
}
|
||
|
|
||
|
// Unpad buf using PKCS#7 from a multiple of n returning a slice of
|
||
|
// buf or an error if malformed.
|
||
|
func Unpad(n int, buf []byte) ([]byte, error) {
|
||
|
if n <= 1 || n >= 256 {
|
||
|
panic("bad multiple")
|
||
|
}
|
||
|
length := len(buf)
|
||
|
if length == 0 {
|
||
|
return nil, ErrorPaddingNotFound
|
||
|
}
|
||
|
if (length % n) != 0 {
|
||
|
return nil, ErrorPaddingNotAMultiple
|
||
|
}
|
||
|
padding := int(buf[length-1])
|
||
|
if padding > n {
|
||
|
return nil, ErrorPaddingTooLong
|
||
|
}
|
||
|
if padding == 0 {
|
||
|
return nil, ErrorPaddingTooShort
|
||
|
}
|
||
|
for i := 0; i < padding; i++ {
|
||
|
if buf[length-1-i] != byte(padding) {
|
||
|
return nil, ErrorPaddingNotAllTheSame
|
||
|
}
|
||
|
}
|
||
|
return buf[:length-padding], nil
|
||
|
}
|