Skip to content

Commit 45c04f5

Browse files
committed
added sha-0 support
1 parent 71f9da2 commit 45c04f5

File tree

2 files changed

+184
-0
lines changed

2 files changed

+184
-0
lines changed

sha.go

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (C) 2014 Space Monkey, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// +build cgo
16+
17+
package openssl
18+
19+
/*
20+
#include <errno.h>
21+
#include <stdio.h>
22+
#include <stdlib.h>
23+
#include <unistd.h>
24+
25+
#include "openssl/evp.h"
26+
*/
27+
import "C"
28+
29+
import (
30+
"errors"
31+
"runtime"
32+
"unsafe"
33+
)
34+
35+
type SHAHash struct {
36+
ctx C.EVP_MD_CTX
37+
engine *Engine
38+
}
39+
40+
func NewSHAHash() (*SHAHash, error) { return NewSHAHashWithEngine(nil) }
41+
42+
func NewSHAHashWithEngine(e *Engine) (*SHAHash, error) {
43+
hash := &SHAHash{engine: e}
44+
C.EVP_MD_CTX_init(&hash.ctx)
45+
runtime.SetFinalizer(hash, func(hash *SHAHash) { hash.Close() })
46+
if err := hash.Reset(); err != nil {
47+
return nil, err
48+
}
49+
return hash, nil
50+
}
51+
52+
func (s *SHAHash) Close() {
53+
C.EVP_MD_CTX_cleanup(&s.ctx)
54+
}
55+
56+
func (s *SHAHash) Reset() error {
57+
if 1 != C.EVP_DigestInit_ex(&s.ctx, C.EVP_sha(), engineRef(s.engine)) {
58+
return errors.New("openssl: sha: cannot init digest ctx")
59+
}
60+
return nil
61+
}
62+
63+
func (s *SHAHash) Write(p []byte) (n int, err error) {
64+
if len(p) == 0 {
65+
return 0, nil
66+
}
67+
if 1 != C.EVP_DigestUpdate(&s.ctx, unsafe.Pointer(&p[0]),
68+
C.size_t(len(p))) {
69+
return 0, errors.New("openssl: sha: cannot update digest")
70+
}
71+
return len(p), nil
72+
}
73+
74+
func (s *SHAHash) Sum() (result [20]byte, err error) {
75+
if 1 != C.EVP_DigestFinal_ex(&s.ctx,
76+
(*C.uchar)(unsafe.Pointer(&result[0])), nil) {
77+
return result, errors.New("openssl: sha: cannot finalize ctx")
78+
}
79+
return result, s.Reset()
80+
}
81+
82+
func SHA(data []byte) (result [20]byte, err error) {
83+
hash, err := NewSHAHash()
84+
if err != nil {
85+
return result, err
86+
}
87+
defer hash.Close()
88+
if _, err := hash.Write(data); err != nil {
89+
return result, err
90+
}
91+
return hash.Sum()
92+
}

sha_test.go

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (C) 2014 Space Monkey, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// +build cgo
16+
17+
package openssl
18+
19+
/*
20+
#include <errno.h>
21+
#include <stdio.h>
22+
#include <stdlib.h>
23+
#include <unistd.h>
24+
25+
#include "openssl/evp.h"
26+
*/
27+
import "C"
28+
29+
import (
30+
"errors"
31+
"runtime"
32+
"unsafe"
33+
)
34+
35+
type SHAHash struct {
36+
ctx C.EVP_MD_CTX
37+
engine *Engine
38+
}
39+
40+
func NewSHAHash() (*SHAHash, error) { return NewSHAHashWithEngine(nil) }
41+
42+
func NewSHAHashWithEngine(e *Engine) (*SHAHash, error) {
43+
hash := &SHAHash{engine: e}
44+
C.EVP_MD_CTX_init(&hash.ctx)
45+
runtime.SetFinalizer(hash, func(hash *SHAHash) { hash.Close() })
46+
if err := hash.Reset(); err != nil {
47+
return nil, err
48+
}
49+
return hash, nil
50+
}
51+
52+
func (s *SHAHash) Close() {
53+
C.EVP_MD_CTX_cleanup(&s.ctx)
54+
}
55+
56+
func (s *SHAHash) Reset() error {
57+
if 1 != C.EVP_DigestInit_ex(&s.ctx, C.EVP_sha(), engineRef(s.engine)) {
58+
return errors.New("openssl: sha: cannot init digest ctx")
59+
}
60+
return nil
61+
}
62+
63+
func (s *SHAHash) Write(p []byte) (n int, err error) {
64+
if len(p) == 0 {
65+
return 0, nil
66+
}
67+
if 1 != C.EVP_DigestUpdate(&s.ctx, unsafe.Pointer(&p[0]),
68+
C.size_t(len(p))) {
69+
return 0, errors.New("openssl: sha: cannot update digest")
70+
}
71+
return len(p), nil
72+
}
73+
74+
func (s *SHAHash) Sum() (result [20]byte, err error) {
75+
if 1 != C.EVP_DigestFinal_ex(&s.ctx,
76+
(*C.uchar)(unsafe.Pointer(&result[0])), nil) {
77+
return result, errors.New("openssl: sha: cannot finalize ctx")
78+
}
79+
return result, s.Reset()
80+
}
81+
82+
func SHA(data []byte) (result [20]byte, err error) {
83+
hash, err := NewSHAHash()
84+
if err != nil {
85+
return result, err
86+
}
87+
defer hash.Close()
88+
if _, err := hash.Write(data); err != nil {
89+
return result, err
90+
}
91+
return hash.Sum()
92+
}

0 commit comments

Comments
 (0)