Пример #1
0
// Sign the given hex-endcoded hash checksum and return a Signature
// @@TODO Remove this -- undeeded
func (pk PrivateKey) SignSHA256(hexbytes []byte) (Signature, error) {
	if hex.DecodedLen(len(hexbytes)) != sha256.Size {
		return nil, ErrPrivateKeySHA256
	}

	// Decode hex bytes into raw bytes
	decodedBytes := make([]byte, hex.DecodedLen(len(hexbytes)))
	_, err := hex.Decode(decodedBytes, hexbytes)
	if err != nil {
		return nil, errors.Wrap(err, ErrPrivateKeySHA256)
	}

	// Get the rsa cryptokey for signing
	cryptoKey, err := pk.GetCryptoKey()
	if err != nil {
		return nil, errors.Wrap(err, ErrPrivatKeySign)
	}

	// Compute the signature and return the results
	rawSignature, err := rsa.SignPKCS1v15(rand.Reader, cryptoKey, crypto.SHA256, decodedBytes)
	if err != nil {
		return nil, errors.Wrap(err, ErrPrivatKeySign)
	}
	return Signature(rawSignature), nil
}
Пример #2
0
func (w *worker) process() {
	go func() {
		// Do the HTTP GET and create the response object
		var resp Response
		httpresp, err := w.client.Get(w.url)
		if httpresp != nil {
			resp = Response{Response: httpresp}
		} else {
			resp = Response{}
		}
		resp.URL = w.url
		resp.Crawler = w.crawler
		if err != nil {
			resp.Err = errors.Wrap(err, ErrReqFailed)
			w.crawler.Handler(&resp)
			w.sendResults(nil, resp.Err)
			return
		}

		// Check headers using HeaderCheck
		if err = w.crawler.CheckHeader(w.crawler, w.url, resp.StatusCode, resp.Header); err != nil {
			resp.Err = errors.Wrap(err, ErrHeaderRejected)
			w.crawler.Handler(&resp)
			resp.Body.Close()
			w.sendResults(nil, resp.Err)
			return
		}

		// Read the body
		resp.bytes, err = ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		if err != nil {
			resp.Err = errors.Wrap(err, ErrBodyRead)
			w.crawler.Handler(&resp)
			w.sendResults(nil, resp.Err)
			return
		}
		// Replace the body with a readCloser that reads from bytes
		resp.Body = &readCloser{bytes.NewReader(resp.bytes)}

		// Process the handler
		w.crawler.Handler(&resp)
		resp.Body = &readCloser{bytes.NewReader(resp.bytes)}

		// Find links and finish
		newurls := make([]string, 0)
		for _, url := range w.crawler.LinkFinder(&resp) {
			if err := w.crawler.CheckURL(w.crawler, url); err == nil {
				newurls = append(newurls, url)
			}
		}

		// We're done, return the results
		w.sendResults(newurls, nil)
	}()
}
Пример #3
0
// Sign the given bytes using naive RSA signing (no hash or padding) and return a Signature using
// This is compatible with blinded messages and blind signatures
func (pk PrivateKey) SignRawBytes(bytes []byte) (Signature, error) {
	cryptoKey, err := pk.GetCryptoKey()
	if err != nil {
		return nil, errors.Wrap(err, ErrPrivatKeySign)
	}
	rawSignature, err := rsa.SignPKCS1v15(rand.Reader, cryptoKey, 0, bytes)
	if err != nil {
		return nil, errors.Wrap(err, ErrPrivatKeySign)
	}
	return Signature(rawSignature), nil
}
Пример #4
0
// Verify that the signature crytpographically signs the given message using the given public key
// This message does not verify using a hash function or padding but verifies using naive RSA verification
func (sig Signature) VerifyRawSignature(pk PublicKey, message []byte) error {
	pubkey, err := pk.GetCryptoKey()
	if err != nil {
		return errors.Wrap(err, ErrSignatureVerify)
	}

	err = rsa.VerifyPKCS1v15(pubkey, 0, message, sig.Bytes())
	if err != nil {
		return errors.Wrap(err, ErrSignatureVerify)
	}
	return err
}
Пример #5
0
// Sign the blinded ballot hash attached to the Signature Request.
// Despite the fact that we sign the SHA256 hash of the ballot, we do not use RSA standard SHA256 hashing and padding
// Instead we do use naive RSA signing to sign the raw signature on the raw hash to ensure compatibility with blinding schemes.
func (sigReq *SignatureRequest) SignBallot(priv PrivateKey) (Signature, error) {
	rawHash := make([]byte, hex.DecodedLen(len(sigReq.BallotHash)))
	_, err := hex.Decode(rawHash, sigReq.BallotHash)
	if err != nil {
		return nil, errors.Wrap(err, ErrSignatureRequestSignBallot)
	}

	sig, err := priv.SignRawBytes(rawHash)
	if err != nil {
		return nil, errors.Wrap(err, ErrSignatureRequestSignBallot)
	}
	return sig, nil
}
Пример #6
0
// Sign the given bytes and return a Signature
// This will use SHA256 as the signing hash function
func (pk PrivateKey) SignBytes(bytes []byte) (Signature, error) {
	h := sha256.New()
	h.Write(bytes)
	cryptoKey, err := pk.GetCryptoKey()
	if err != nil {
		return nil, errors.Wrap(err, ErrPrivatKeySign)
	}
	rawSignature, err := rsa.SignPKCS1v15(rand.Reader, cryptoKey, crypto.SHA256, h.Sum(nil))
	if err != nil {
		return nil, errors.Wrap(err, ErrPrivatKeySign)
	}
	return Signature(rawSignature), nil
}
Пример #7
0
// Verify that the signature crytpographically signs the given message using the given public key
func (sig Signature) VerifySignature(pk PublicKey, message []byte) error {
	pubkey, err := pk.GetCryptoKey()
	if err != nil {
		return errors.Wrap(err, ErrSignatureVerify)
	}

	hash := sha256.New()
	hash.Write(message)
	err = rsa.VerifyPKCS1v15(pubkey, crypto.SHA256, hash.Sum(nil), sig.Bytes())
	if err != nil {
		return errors.Wrap(err, ErrSignatureVerify)
	}
	return err
}
Пример #8
0
// Parse the PrivateKey (which is stored as a der encoded key) into a rsa.PrivateKey object, ready to be used for crypto functions
func (pk PrivateKey) GetCryptoKey() (*rsa.PrivateKey, error) {
	privkey, err := x509.ParsePKCS1PrivateKey(pk.Bytes())
	if err != nil {
		return nil, errors.Wrap(err, ErrPrivatKeyCryptoKey)
	}
	return privkey, nil
}
Пример #9
0
// Generate a new PrivateKey
func GeneratePrivateKey(keySize int) (PrivateKey, error) {
	cryptoKey, err := rsa.GenerateKey(rand.Reader, keySize)
	if err != nil {
		return nil, errors.Wrap(err, ErrPrivatKeyGenerate)
	}
	return NewPrivateKeyFromCryptoKey(cryptoKey), nil
}
Пример #10
0
// Parse the PublicKey (which is stored as a der encoded key) into a rsa.PublicKey object, ready to be used for crypto functions
func (pk PublicKey) GetCryptoKey() (*rsa.PublicKey, error) {
	pubkey, err := x509.ParsePKIXPublicKey(pk.Bytes())
	if err != nil {
		return nil, errors.Wrap(err, ErrPublicKeyCryptoKey)
	}
	return pubkey.(*rsa.PublicKey), nil
}
Пример #11
0
// Get the number of bits in the key
func (pk PublicKey) KeyLength() (int, error) {
	pubkey, err := pk.GetCryptoKey()
	if err != nil {
		return 0, errors.Wrap(err, ErrPublicKeyLen)
	}
	return pubkey.N.BitLen(), nil
}
Пример #12
0
// Create a new PrivateKey from a pem.Block
// This function also performs error checking to make sure the key is valid.
func NewPrivateKeyFromBlock(PEMBlock *pem.Block) (PrivateKey, error) {
	if PEMBlock.Type != "RSA PRIVATE KEY" {
		return nil, errors.Wraps(ErrPrivatKeyWrongType, "Found "+PEMBlock.Type)
	}

	_, err := x509.ParsePKCS1PrivateKey(PEMBlock.Bytes)
	if err != nil {
		return nil, errors.Wrap(ErrPrivatKeyInvalidPEM, err)
	}

	return PrivateKey(PEMBlock.Bytes), nil
}
Пример #13
0
// Create a new signature from a base64 encoded item, as we would get in a PUT or POST request
//@@TODO: Test to make sure "Signature too short" is working as expected
func NewSignature(Base64Signature []byte) (Signature, error) {
	dbuf := make([]byte, base64.StdEncoding.DecodedLen(len(Base64Signature)))
	n, err := base64.StdEncoding.Decode(dbuf, Base64Signature)
	if err != nil {
		return nil, errors.Wrap(err, ErrSignatureBase64)
	}
	if n < 128 {
		return nil, ErrSignatureTooShort
	}
	sig := dbuf[:n]

	return Signature(sig), nil
}
Пример #14
0
func NewUserFromBlock(PEMBlock *pem.Block) (*User, error) {
	var (
		err       error
		publicKey PublicKey
		perms     []string
	)

	if PEMBlock.Type != "PUBLIC KEY" {
		return nil, errors.Wraps(ErrUserBlockNotFound, "Unexpected "+PEMBlock.Type)
	}

	publicCryptoKey, err := x509.ParsePKIXPublicKey(PEMBlock.Bytes)
	if err != nil {
		return nil, errors.Wrap(err, ErrUserInvalidPEM)
	}

	publicKey, err = NewPublicKeyFromCryptoKey(publicCryptoKey.(*rsa.PublicKey))
	if err != nil {
		return nil, err
	}

	permString, ok := PEMBlock.Headers["perms"]
	if !ok || permString == "" {
		return nil, ErrUserPermsNotFound
	}
	permsRaw := strings.Split(permString, ",")
	for _, val := range permsRaw {
		trimmed := strings.TrimSpace(val)
		if trimmed == "" {
			return nil, ErrUserPermsInvalid
		}
		perms = append(perms, trimmed)
	}

	// All checks pass
	return &User{
		publicKey,
		perms,
		PEMBlock.Headers,
	}, nil
}
Пример #15
0
// Create a new PublicKey from a base64 encoded item, as we would get in a PUT or POST request
// This function also performs error checking to make sure the key is valid.
func NewPublicKey(base64PublicKey []byte) (PublicKey, error) {
	decodedLen := base64.StdEncoding.DecodedLen(len(base64PublicKey))
	dbuf := make([]byte, decodedLen)
	n, err := base64.StdEncoding.Decode(dbuf, base64PublicKey)
	if err != nil {
		return nil, errors.Wrap(err, ErrPublicKeyBase64)
	}
	pk := PublicKey(dbuf[:n])

	// Check the key length
	keylen, err := pk.KeyLength()
	if err != nil {
		return nil, err
	}
	if MinPublicKeySize < absoluteMinPublicKeySize {
		panic("MinPublicKeySize has been set less than the allowed absoluteMinPublicKeySize of 2048")
	}
	if keylen < MinPublicKeySize {
		return nil, errors.Wrapf(ErrPubicMinKeySize, "Please use at least %s bits for public-key", MinPublicKeySize)
	}

	return pk, nil
}
Пример #16
0
func NewElection(rawElection []byte) (*Election, error) {
	var (
		tagsSec    int
		keySec     int
		signSec    int
		err        error
		electionID string
		start      time.Time
		end        time.Time
		publicKey  PublicKey
		tagSet     TagSet
		signature  Signature
	)

	// Split the election into parts seperated by a double linebreak
	parts := bytes.Split(rawElection, []byte("\n\n"))

	// Determine what components exist
	numParts := len(parts)
	switch numParts {
	case 6:
		tagsSec = 3
		keySec = 4
		signSec = 5
	case 5:
		// We need to determine if the signature is missing or if the tagset is missing
		// We do this by looking at the 4th element (index 3) and checking to see if it's a tagset or the public key
		if bytes.Contains(parts[3], []byte{'\n'}) {
			// If it contains a linebreak, it's a tagset. The signature is missing.
			tagsSec = 3
			keySec = 4
		} else {
			// It's a public-key. There is a signature but no tagset.
			keySec = 3
			signSec = 4
		}
	case 4:
		keySec = 3
	default:
		return &Election{}, ErrEelectionInvalid
	}

	electionID = string(parts[0])
	if len(electionID) > MaxElectionIDSize {
		return &Election{}, ErrElectionIDTooBig
	}
	if !ValidElectionID.MatchString(electionID) {
		return &Election{}, ErrElectionIDInvalid
	}

	start, err = time.Parse(time.RFC1123Z, string(parts[1]))
	if err != nil {
		return &Election{}, errors.Wrap(err, ErrElectionStartInvalid)
	}

	end, err = time.Parse(time.RFC1123Z, string(parts[2]))
	if err != nil {
		return &Election{}, errors.Wrap(err, ErrElectionEndInvalid)
	}

	if tagsSec != 0 {
		tagSet, err = NewTagSet(parts[tagsSec])
		if err != nil {
			return &Election{}, errors.Wrap(err, ErrElectionInvalidTagSet)
		}
	} else {
		tagSet = nil
	}

	publicKey, err = NewPublicKey(parts[keySec])
	if err != nil {
		return &Election{}, errors.Wrap(err, ErrElectionInvalidKey)
	}

	if signSec != 0 {
		signature, err = NewSignature(parts[signSec])
		if err != nil {
			return &Election{}, errors.Wrap(err, ErrElectionInvalidSig)
		}
	} else {
		signature = nil
	}

	// All checks pass, create and return the election
	election := Election{
		electionID,
		start,
		end,
		tagSet,
		publicKey,
		signature,
	}
	return &election, nil
}
Пример #17
0
func FooWrappingStdError() error {
	return errors.Wrap(ErrStd, ErrFoo)
}
Пример #18
0
// Given a raw Signature Request string (as a []byte -- see documentation for format), return a new SignatureRequest object.
// Generally the Signature Request string is coming from a voter in a POST body.
// This will also verify the signature on the SignatureRequest and return an error if the request does not pass crypto verification
func NewSignatureRequest(rawSignatureRequest []byte) (*SignatureRequest, error) {
	var (
		err        error
		hasSign    bool
		electionID string
		requestID  []byte
		publicKey  PublicKey
		ballotHash []byte
		signature  Signature
	)

	// The SignatureRequest is composed of individual components seperated by double linebreaks
	parts := bytes.Split(rawSignatureRequest, []byte("\n\n"))

	numParts := len(parts)
	switch {
	case numParts == 4:
		hasSign = false
	case numParts == 5:
		hasSign = true
	default:
		return &SignatureRequest{}, ErrSignatureRequestInvalid
	}

	electionID = string(parts[0])

	publicKey, err = NewPublicKey(parts[2])
	if err != nil {
		return &SignatureRequest{}, errors.Wrap(err, ErrSignatureRequestPublicKey)
	}

	requestID = parts[1]
	if !bytes.Equal(requestID, publicKey.GetSHA256()) {
		return &SignatureRequest{}, ErrSignatureRequestID
	}

	ballotHash = parts[3]
	n, err := hex.Decode(make([]byte, hex.DecodedLen(len(ballotHash))), ballotHash)
	if err != nil {
		return &SignatureRequest{}, ErrSignatureRequestBallotHash
	}
	if n != sha256.Size {
		return &SignatureRequest{}, ErrSignatureRequestHashBits
	}

	if hasSign {
		signature, err = NewSignature(parts[4])
		if err != nil {
			return &SignatureRequest{}, errors.Wrap(err, ErrSignatureRequestSigInvalid)
		}
	} else {
		signature = nil
	}

	sigReq := SignatureRequest{
		electionID,
		requestID,
		publicKey,
		ballotHash,
		signature,
	}

	// All checks pass
	return &sigReq, nil
}
Пример #19
0
func StdErrorWrappingFoo() error {
	return errors.Wrap(ErrFoo, ErrStd) // should panic
}
Пример #20
0
func main() {
	err1 := errors.Wrap(Err1, Err2)
	err2 := errors.Append(Err2, Err1)
	fmt.Printf("%T: %v\n", err1, err1)
	fmt.Printf("%T: %v\n", err2, err2)
}
Пример #21
0
func FooWrappingBar() error {
	return errors.Wrap(ErrBar, ErrFoo)
}
Пример #22
0
// Given a raw ballot-string (as a []byte) (see documentation for format), return a new Ballot.
// Generally the ballot-string is coming from a client in a PUT body.
// This will also verify the signature on the ballot and return an error if the ballot does not pass crypto verification
func NewBallot(rawBallot []byte) (*Ballot, error) {
	var (
		tagsSec    int
		signSec    int
		err        error
		electionID string
		ballotID   string
		vote       Vote
		tagSet     TagSet
		signature  Signature
	)

	// Check it's size
	if len(rawBallot) > MaxBallotSize {
		return nil, ErrBallotTooBig
	}

	// Split the ballot into parts seperated by a double linebreak
	parts := bytes.Split(rawBallot, []byte("\n\n"))

	// Determine what components exist
	numParts := len(parts)
	switch numParts {
	case 3:
		tagsSec = 0
		signSec = 0
	case 4:
		// We need to determine if the last element in the ballot is a tag or a signature
		if bytes.Contains(parts[3], []byte{'\n'}) {
			// If it contains a linebreak, it's a tagset
			tagsSec = 3
			signSec = 0
		} else {
			// We need to test by looking at length. The maximum tagset size is smaller than the smallest signature
			if len(parts[3]) > (MaxTagKeySize + MaxTagValueSize + 1) {
				tagsSec = 0
				signSec = 3
			} else {
				tagsSec = 3
				signSec = 0
			}
		}
	case 5:
		tagsSec = 3
		signSec = 4
	default:
		return &Ballot{}, ErrBallotInvalid
	}

	electionID = string(parts[0])
	if len(electionID) > MaxElectionIDSize {
		return &Ballot{}, ErrElectionIDTooBig
	}
	if !ValidElectionID.MatchString(electionID) {
		return &Ballot{}, ErrElectionIDInvalid
	}

	ballotID = string(parts[1])
	if len(ballotID) > MaxBallotIDSize {
		return &Ballot{}, ErrBallotIDTooBig
	}
	if !ValidBallotID.MatchString(ballotID) {
		return &Ballot{}, ErrBallotIDInvalid
	}

	vote, err = NewVote(parts[2])
	if err != nil {
		return &Ballot{}, errors.Wrap(err, ErrBallotInvalidVote)
	}

	if tagsSec != 0 {
		tagSet, err = NewTagSet(parts[tagsSec])
		if err != nil {
			return &Ballot{}, errors.Wrap(err, ErrBallotInvalidTagSet)
		}
	} else {
		tagSet = nil
	}

	if signSec != 0 {
		signature, err = NewSignature(parts[signSec])
		if err != nil {
			return &Ballot{}, errors.Wrap(err, ErrBallotInvalidSig)
		}
	} else {
		signature = nil
	}

	// All checks pass, create and return the ballot
	ballot := Ballot{
		electionID,
		ballotID,
		vote,
		tagSet,
		signature,
	}
	return &ballot, nil
}