First commit
This commit is contained in:
parent
f292f9b79f
commit
e40281a273
102
encrypted.go
Normal file
102
encrypted.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// Implements MIME security with OpenPGP, as defined in RFC 3156.
|
||||||
|
package pgpmime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"mime/multipart"
|
||||||
|
"net/textproto"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/openpgp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A PGP/MIME encrypter.
|
||||||
|
type Encrypter struct {
|
||||||
|
multipart *multipart.Writer
|
||||||
|
armored io.WriteCloser
|
||||||
|
encrypted io.WriteCloser
|
||||||
|
|
||||||
|
to []*openpgp.Entity
|
||||||
|
signed *openpgp.Entity
|
||||||
|
|
||||||
|
opened bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write control information and create encrypted part.
|
||||||
|
func (ew *Encrypter) open() (err error) {
|
||||||
|
// Create control information
|
||||||
|
h := make(textproto.MIMEHeader)
|
||||||
|
h.Add("Content-Type", "application/pgp-encrypted")
|
||||||
|
hw, err := ew.multipart.CreatePart(h)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err = io.WriteString(hw, "Version: 1\r\n"); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create body part
|
||||||
|
h = make(textproto.MIMEHeader)
|
||||||
|
h.Add("Content-Type", "application/octet-stream")
|
||||||
|
h.Add("Content-Disposition", "inline")
|
||||||
|
bw, err := ew.multipart.CreatePart(h)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create encrypted part
|
||||||
|
if ew.armored, err = EncodeArmoredMessage(bw); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ew.encrypted, err = openpgp.Encrypt(ew.armored, ew.to, ew.signed, nil, nil); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write encrypted data.
|
||||||
|
func (ew *Encrypter) Write(b []byte) (n int, err error) {
|
||||||
|
// Make sure parts required at the begining of the message have been written
|
||||||
|
if !ew.opened {
|
||||||
|
if err = ew.open(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ew.opened = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return ew.encrypted.Write(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish the PGP/MIME message.
|
||||||
|
func (ew *Encrypter) Close() (err error) {
|
||||||
|
if !ew.opened {
|
||||||
|
if err = ew.open(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ew.opened = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = ew.encrypted.Close(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = ew.armored.Close(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = ew.multipart.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the Content-Type of this PGP/MIME message.
|
||||||
|
func (ew *Encrypter) ContentType() string {
|
||||||
|
return "multipart/encrypted; boundary=" + ew.multipart.Boundary() + "; protocol=\"application/pgp-encrypted\""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new PGP/MIME encrypter.
|
||||||
|
func NewEncrypter(w io.Writer, to []*openpgp.Entity, signed *openpgp.Entity) *Encrypter {
|
||||||
|
return &Encrypter{
|
||||||
|
multipart: multipart.NewWriter(w),
|
||||||
|
|
||||||
|
to: to,
|
||||||
|
signed: signed,
|
||||||
|
}
|
||||||
|
}
|
32
message.go
Normal file
32
message.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package pgpmime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/openpgp/armor"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Armored type for PGP encrypted messages.
|
||||||
|
const MessageType = "PGP MESSAGE"
|
||||||
|
|
||||||
|
// Encode a PGP message armor.
|
||||||
|
func EncodeArmoredMessage(w io.Writer) (io.WriteCloser, error) {
|
||||||
|
return armor.Encode(w, MessageType, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode an armored PGP message.
|
||||||
|
func DecodeArmoredMessage(in io.Reader) (out io.Reader, err error) {
|
||||||
|
block, err := armor.Decode(in)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if block.Type != MessageType {
|
||||||
|
err = errors.New("Not an armored PGP message")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out = block.Body
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user