pkcs7

package module
v0.0.0-...-916a162 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 5, 2022 License: MIT Imports: 13 Imported by: 1

README

pault.ag/go/pkcs7

godocs can be found here

Pure-Go implemntation of the PKCS#7 specification.

WARNING

This implementation is like totally super not implemented all the way through. When this blows up, puts a hole through your screen and deletes all your data, please don't blame me.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// If the PKCS#7 implemtation here doesn't know what to do with that Content Type,
	// we'll bail out of the function with one of these guys.
	UnsupportedContent = fmt.Errorf("pkcs7: unsupported content type")

	// If the PKCS#7 decryption bits don't know how to decrypt the message,
	// we're going to go ahead and tell the user we don't know what's up.
	UnsupportedAlgorithm = fmt.Errorf("pkcs7: unsupported algorithm")

	// If we can't find a matching x509 Certificate in the RecipientInfo list,
	// we'll drop this out of Error. Matching is done based on Issuer bytes
	// and Serial. If you know exactly what is going on (e.g. Self-Signed and
	// you didn't keep it around because lol self signed certificates aren't
	// real), you can go ahead and manually fiddle the internals.
	NoMatchingCertificate = fmt.Errorf("pkcs7: can't find your cert")

	// If we can't find a matching asn1 ObjectIdentifier, go ahead and throw
	// one of these suckas.
	NoMatchingAttribute = fmt.Errorf("pkcs7: can't find the right attribute")

	// If we can't find a hashing algorithm that matches the one we want, we
	// might return this fella'
	NoMatchingAlgorithm = fmt.Errorf("pkcs7: can't find the right hashing algorithm")
)
View Source
var (
	// Data encapsulation
	OIDEnvelopedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 3}
	OIDSignedData    = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2}
	OIDData          = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1}
)

Functions

func Pad

func Pad(data []byte, blockSize uint) ([]byte, error)

func Unpad

func Unpad(data []byte, blockSize uint) ([]byte, error)

Types

type Attribute

type Attribute struct {
	Type  asn1.ObjectIdentifier
	Value asn1.RawValue
}

func NewAttribute

func NewAttribute(oid asn1.ObjectIdentifier, data interface{}) (*Attribute, error)

type AttributeSet

type AttributeSet struct {
	Attributes Attributes `asn1:"set"`
}

type Attributes

type Attributes []Attribute

func (Attributes) Find

func (a Attributes) Find(attributeType asn1.ObjectIdentifier) (*Attribute, error)

func (Attributes) Unmarshal

func (a Attributes) Unmarshal(attributeType asn1.ObjectIdentifier, out interface{}) error

type ContentInfo

type ContentInfo struct {
	Type    asn1.ObjectIdentifier
	Content asn1.RawValue `asn1:"explicit,optional,tag:0`
}

ContentInfo encapsulation. This is the top level struct. One can then dispatch based on `Type`, and call the right method(s).

func Data

func Data(data []byte) (*ContentInfo, error)

func Encrypt

func Encrypt(rand io.Reader, to []x509.Certificate, plaintext []byte) (*ContentInfo, error)

func Parse

func Parse(data []byte) (*ContentInfo, error)

DER encoded only pls

func Sign

func Sign(rand io.Reader, contentInfo ContentInfo, cert x509.Certificate, signer crypto.Signer, opts crypto.SignerOpts) (*ContentInfo, error)

func (ContentInfo) EnvelopedData

func (c ContentInfo) EnvelopedData() (*EnvelopedData, error)

Get the EnvelopedData struct out of the body of the Content. If the content is not Enveloped, we'll return an error. otherwise, we'll unpack the encrypted goodness into a EnvelopedData struct.

func (ContentInfo) Marshal

func (c ContentInfo) Marshal() ([]byte, error)

func (ContentInfo) RawContent

func (c ContentInfo) RawContent() ([]byte, error)

func (ContentInfo) SignedData

func (c ContentInfo) SignedData() (*SignedData, error)

type EncryptedContentInfo

type EncryptedContentInfo struct {
	Type      asn1.ObjectIdentifier
	Algorithm pkix.AlgorithmIdentifier
	Content   asn1.RawValue `asn1:"optional,tag:0"`
}

func (EncryptedContentInfo) RawDecrypt

func (e EncryptedContentInfo) RawDecrypt(key []byte) ([]byte, error)

For users who know what they're doing, here's the knob.

type EnvelopedData

type EnvelopedData struct {
	Version              int
	Recipients           Recipients `asn1:"set"`
	EncryptedContentInfo EncryptedContentInfo
}

func (EnvelopedData) Decrypt

func (e EnvelopedData) Decrypt(rand io.Reader, cert x509.Certificate, decrypter crypto.Decrypter, opts crypto.DecrypterOpts) ([]byte, error)

type IssuerAndSerialNumber

type IssuerAndSerialNumber struct {
	Issuer asn1.RawValue
	Serial *big.Int
}

func (IssuerAndSerialNumber) Matches

func (i IssuerAndSerialNumber) Matches(cert x509.Certificate) bool

type RawCertificates

type RawCertificates struct {
	Raw asn1.RawContent
}

func (RawCertificates) Certificates

func (gah RawCertificates) Certificates() ([]*x509.Certificate, error)

type RecipientInfo

type RecipientInfo struct {
	Version                int
	IssuerAndSerialNumber  IssuerAndSerialNumber
	KeyEncryptionAlgorithm pkix.AlgorithmIdentifier
	EncryptedKey           []byte
}

func (RecipientInfo) Decrypt

func (r RecipientInfo) Decrypt(
	rand io.Reader,
	decrypter crypto.Decrypter,
	opts crypto.DecrypterOpts,
) ([]byte, error)

Get the content key out of the EncryptedKey entry

func (RecipientInfo) Matches

func (r RecipientInfo) Matches(cert x509.Certificate) bool

Check to see if the RecipientInfo Serial and Issuer match our Certificate.

type Recipients

type Recipients []RecipientInfo

func (Recipients) Find

func (r Recipients) Find(cert x509.Certificate) (*RecipientInfo, error)

Given a list of RecipientInfo objects, find the matching RecipientInfo entry by seeing which Serial and Issuer matches our certificate. If no matching RecipientInfo is found, we'll return a `NoMatchingCertificate` error.

type SignedData

type SignedData struct {
	Version                    int                        `asn1:"default:1"`
	DigestAlgorithmIdentifiers []pkix.AlgorithmIdentifier `asn1:"set"`
	ContentInfo                ContentInfo
	RawCertificates            RawCertificates        `asn1:"optional,tag:0"`
	CRLs                       []pkix.CertificateList `asn1:"optional,tag:1"`
	SignerInfo                 SignersInfo            `asn1:"set"`
}

func NewSignedData

func NewSignedData(contentInfo ContentInfo) (*SignedData, error)

func (*SignedData) AddCertificate

func (sd *SignedData) AddCertificate(cert x509.Certificate) error

func (*SignedData) AddDigestAlgorithmIdentifier

func (sd *SignedData) AddDigestAlgorithmIdentifier(id pkix.AlgorithmIdentifier) error

func (SignedData) Certificates

func (s SignedData) Certificates() ([]*x509.Certificate, error)

func (SignedData) CreateContentInfo

func (sd SignedData) CreateContentInfo() (*ContentInfo, error)

func (*SignedData) Sign

func (sd *SignedData) Sign(
	rand io.Reader,

	cert x509.Certificate,

	signer crypto.Signer,
	opts crypto.SignerOpts,

	signedAttributes Attributes,
	unsignedAttributes Attributes,
) error

func (SignedData) Verify

func (s SignedData) Verify(cert x509.Certificate) error

Explictly pass in the x509 Certificate we're checking against. If I was a clever attacker, I might just make a self-signed TLS certificate with the same issuer and serial, and hope no one checks too closely that it's not the same same. As a result, if you plan on trusting the cert that's coming across the line, It's on you to load and verify you've got the right cert in your hand.

This means we won't check the CA signature, NotAfter, NotBefore, KeyUsage, or anything else. That's on you, buddy!

func (SignedData) VerifyHash

func (s SignedData) VerifyHash(signerInfo SignerInfo, cert x509.Certificate) ([]byte, error)

func (SignedData) VerifySignature

func (s SignedData) VerifySignature(signerInfo SignerInfo, cert x509.Certificate) error

type SignerInfo

type SignerInfo struct {
	Version                   int
	IssuerAndSerialNumber     IssuerAndSerialNumber
	DigestAlgorithm           pkix.AlgorithmIdentifier
	AuthenticatedAttributes   Attributes `asn1:"optional,tag:0"`
	DigestEncryptionAlgorithm pkix.AlgorithmIdentifier
	EncryptedDigest           []byte
	UnauthenticatedAttributes Attributes `asn1:"optional,tag:1"`
}

func (SignerInfo) Matches

func (s SignerInfo) Matches(cert x509.Certificate) bool

type SignersInfo

type SignersInfo []SignerInfo

func (SignersInfo) Find

func (s SignersInfo) Find(cert x509.Certificate) (*SignerInfo, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL