Skip to content

Commit ea7f327

Browse files
committed
Adding PKCS#8 support of scrypt
1 parent f27c768 commit ea7f327

File tree

4 files changed

+203
-4
lines changed

4 files changed

+203
-4
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
;;; -*- mode:scheme; coding:utf-8; -*-
2+
;;;
3+
;;; sagittarius/crypto/pkix/modules/scrypt.scm - scrypt module
4+
;;;
5+
;;; Copyright (c) 2022 Takashi Kato <ktakashi@ymail.com>
6+
;;;
7+
;;; Redistribution and use in source and binary forms, with or without
8+
;;; modification, are permitted provided that the following conditions
9+
;;; are met:
10+
;;;
11+
;;; 1. Redistributions of source code must retain the above copyright
12+
;;; notice, this list of conditions and the following disclaimer.
13+
;;;
14+
;;; 2. Redistributions in binary form must reproduce the above copyright
15+
;;; notice, this list of conditions and the following disclaimer in the
16+
;;; documentation and/or other materials provided with the distribution.
17+
;;;
18+
;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
;;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
;;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21+
;;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22+
;;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
;;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24+
;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25+
;;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26+
;;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27+
;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28+
;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
;;;
30+
31+
;; ref
32+
;; - https://datatracker.ietf.org/doc/html/rfc7914
33+
#!nounbound
34+
(library (sagittarius crypto pkcs modules scrypt)
35+
(export *pbes:scrypt*
36+
scrypt-params? <scrypt-params>
37+
scrypt-params-salt
38+
scrypt-params-cost-parameter
39+
scrypt-params-block-size
40+
scrypt-params-parallelization-parameter
41+
scrypt-params-key-length)
42+
(import (rnrs)
43+
(clos user)
44+
(sagittarius crypto asn1)
45+
(sagittarius crypto asn1 modules))
46+
(define oid oid-string->der-object-identifier)
47+
(define *pbes:scrypt* (oid "1.3.6.1.4.1.11591.4.11"))
48+
49+
;; scrypt-params ::= SEQUENCE {
50+
;; salt OCTET STRING,
51+
;; costParameter INTEGER (1..MAX),
52+
;; blockSize INTEGER (1..MAX),
53+
;; parallelizationParameter INTEGER (1..MAX),
54+
;; keyLength INTEGER (1..MAX) OPTIONAL }
55+
(define-asn1-encodable <scrypt-params>
56+
(asn1-sequence
57+
((salt :type <der-octet-string> :reader scrypt-params-salt)
58+
(cost-parameter :type <der-integer> :reader scrypt-params-cost-parameter)
59+
(block-size :type <der-integer> :reader scrypt-params-block-size)
60+
(parallelization-parameter :type <der-integer>
61+
:reader scrypt-params-parallelization-parameter)
62+
(key-length :type <der-integer> :optional #t
63+
:reader scrypt-params-key-length))))
64+
(define (scrypt-params? o) (is-a? o <scrypt-params>))
65+
)

ext/crypto/sagittarius/crypto/pkcs/pbes.scm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@
8989

9090
encryption-scheme->cipher-parameters
9191
parameter->key-length ;; for default key length
92+
;; for other KDFs
93+
(rename (check-key-length encryption-scheme->key-length))
9294
)
9395
(import (rnrs)
9496
(clos user)
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
;;; -*- mode:scheme; coding:utf-8; -*-
2+
;;;
3+
;;; sagittarius/crypto/pkix/scrypt.scm - scrypt for PKCS
4+
;;;
5+
;;; Copyright (c) 2022 Takashi Kato <ktakashi@ymail.com>
6+
;;;
7+
;;; Redistribution and use in source and binary forms, with or without
8+
;;; modification, are permitted provided that the following conditions
9+
;;; are met:
10+
;;;
11+
;;; 1. Redistributions of source code must retain the above copyright
12+
;;; notice, this list of conditions and the following disclaimer.
13+
;;;
14+
;;; 2. Redistributions in binary form must reproduce the above copyright
15+
;;; notice, this list of conditions and the following disclaimer in the
16+
;;; documentation and/or other materials provided with the distribution.
17+
;;;
18+
;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
;;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
;;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21+
;;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22+
;;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23+
;;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24+
;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25+
;;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26+
;;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27+
;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28+
;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
;;;
30+
31+
;; ref
32+
;; - https://datatracker.ietf.org/doc/html/rfc7914
33+
#!nounbound
34+
(library (sagittarius crypto pkcs scrypt)
35+
(export *pbes:scrypt*
36+
pkcs-scrypt-params? <pkcs-scrypt-params>
37+
make-pkcs-scrypt-params
38+
pkcs-scrypt-params-salt
39+
pkcs-scrypt-params-cost-parameter
40+
pkcs-scrypt-params-block-size
41+
pkcs-scrypt-params-parallelization-parameter
42+
pkcs-scrypt-params-key-length
43+
)
44+
(import (rnrs)
45+
(clos user)
46+
(sagittarius crypto asn1)
47+
(sagittarius crypto asn1 modules)
48+
(sagittarius crypto kdfs scrypt)
49+
(sagittarius crypto pkcs modules scrypt)
50+
(sagittarius crypto pkcs algorithms)
51+
(sagittarius crypto pkcs modules pbes)
52+
(sagittarius crypto pkcs pbes) ;; for <pkcs-pbes2-params>
53+
(sagittarius crypto pkix algorithms)
54+
(sagittarius crypto pkix modules x509)
55+
(sagittarius combinators))
56+
(define sid der-object-identifier->oid-string)
57+
(define (make-slot-ref getter conv) (lambda (o) (conv (getter o))))
58+
(define-class <pkcs-scrypt-params>
59+
(<asn1-encodable-container> <x509-algorithm-parameters>)
60+
((salt :allocation :virtual :cached #t
61+
:slot-ref (make-slot-ref
62+
(.$ scrypt-params-salt asn1-encodable-container-c)
63+
der-octet-string->bytevector)
64+
:reader pkcs-scrypt-params-salt)
65+
(cost-parameter :allocation :virtual :cached #t
66+
:slot-ref (make-slot-ref
67+
(.$ scrypt-params-cost-parameter asn1-encodable-container-c)
68+
der-integer->integer)
69+
:reader pkcs-scrypt-params-cost-parameter)
70+
(block-size :allocation :virtual :cached #t
71+
:slot-ref (make-slot-ref
72+
(.$ scrypt-params-block-size asn1-encodable-container-c)
73+
der-integer->integer)
74+
:reader pkcs-scrypt-params-block-size)
75+
(parallelization-parameter :allocation :virtual :cached #t
76+
:slot-ref (make-slot-ref
77+
(.$ scrypt-params-parallelization-parameter
78+
asn1-encodable-container-c)
79+
der-integer->integer)
80+
:reader pkcs-scrypt-params-parallelization-parameter)
81+
(key-length :allocation :virtual :cached #t
82+
:slot-ref (make-slot-ref
83+
(.$ scrypt-params-key-length
84+
asn1-encodable-container-c)
85+
(lambda (v) (and v (der-integer->integer v))))
86+
:reader pkcs-scrypt-params-key-length)))
87+
(define (pkcs-scrypt-params? o) (is-a? o <pkcs-scrypt-params>))
88+
(define (make-pkcs-scrypt-params (salt bytevector?)
89+
(cost-parameter integer?)
90+
(block-size integer?)
91+
(parallelization-parameter integer?)
92+
:key (key-length #f))
93+
(make <pkcs-scrypt-params>
94+
:c (make <scrypt-params>
95+
:salt (bytevector->der-octet-string salt)
96+
:cost-parameter (integer->der-integer cost-parameter)
97+
:block-size (integer->der-integer block-size)
98+
:parallelization-parameter (integer->der-integer parallelization-parameter)
99+
:key-length (and key-length (integer->der-integer key-length)))))
100+
101+
(define-method oid->x509-algorithm-parameters-types
102+
((oid (equal (sid *pbes:scrypt*))))
103+
(values <pkcs-scrypt-params> <scrypt-params>))
104+
(define-method oid->kdf ((oid (equal (sid *pbes:scrypt*))) kdf-param pbes2-param)
105+
(define enc (pkcs-pbes2-params-encryption-scheme pbes2-param))
106+
(define dk-len (or (pkcs-scrypt-params-key-length kdf-param)
107+
(encryption-scheme->key-length enc)))
108+
(lambda (key . ignore)
109+
(scrypt (string->utf8 key)
110+
(pkcs-scrypt-params-salt kdf-param)
111+
(pkcs-scrypt-params-cost-parameter kdf-param)
112+
(pkcs-scrypt-params-block-size kdf-param)
113+
(pkcs-scrypt-params-parallelization-parameter kdf-param)
114+
dk-len)))
115+
)

ext/crypto/tests/test-pkcs8.scm

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
(import (rnrs)
2+
(sagittarius)
23
(sagittarius crypto asn1)
34
(sagittarius crypto pkcs keys)
45
(sagittarius crypto pkcs pbes)
6+
(sagittarius crypto pkcs scrypt)
57
(sagittarius crypto pkix algorithms)
68
(sagittarius crypto keys)
79
(rfc base64)
@@ -51,17 +53,30 @@
5153
"UprPtDydck9skek3R246Xw==")
5254
:transcoder #f))
5355

56+
;; scrypt + AES256 CBC
57+
(define epki4
58+
(base64-decode-string
59+
(string-append
60+
"MIHiME0GCSqGSIb3DQEFDTBAMB8GCSsGAQQB2kcECzASBAVNb3VzZQIDEAAAAgEI"
61+
"AgEBMB0GCWCGSAFlAwQBKgQQyYmguHMsOwzGMPoyObk/JgSBkJb47EWd5iAqJlyy"
62+
"+ni5ftd6gZgOPaLQClL7mEZc2KQay0VhjZm/7MbBUNbqOAXNM6OGebXxVp6sHUAL"
63+
"iBGY/Dls7B1TsWeGObE0sS1MXEpuREuloZjcsNVcNXWPlLdZtkSH6uwWzR0PyG/Z"
64+
"+ZXfNodZtd/voKlvLOw5B3opGIFaLkbtLZQwMiGtl42AS89lZg==")
65+
:transcoder #f))
66+
5467
(test-begin "PKCS#8")
5568

5669
(define password "test1234")
57-
(define (test-pbe bv)
70+
(define (test-pbe bv password)
5871
(test-assert (pkcs-encrypted-private-key-info?
5972
(bytevector->pkcs-encrypted-private-key-info bv)))
6073
(let ((epki (bytevector->pkcs-encrypted-private-key-info bv)))
6174
(test-assert (x509-algorithm-identifier?
6275
(pkcs-encrypted-private-key-info-encryption-algorithm epki)))
6376
(test-assert (bytevector?
6477
(pkcs-encrypted-private-key-info-encrypted-data epki)))
78+
(test-error (pkcs-encrypted-private-key-info->pkcs-one-asymmetric-key
79+
epki "this password is not correct"))
6580
(let ((pki (pkcs-encrypted-private-key-info->pkcs-one-asymmetric-key
6681
epki password)))
6782
(test-assert (pkcs-one-asymmetric-key? pki))
@@ -79,9 +94,11 @@
7994
(pkcs-encrypted-private-key-info->pkcs-one-asymmetric-key
8095
epki2 password)))))))
8196

82-
(test-pbe epki1)
83-
(test-pbe epki2)
84-
(test-pbe epki3)
97+
(test-pbe epki1 password)
98+
(test-pbe epki2 password)
99+
(test-pbe epki3 password)
100+
;; It's too heavy to do it on CI...
101+
(unless (getenv "CI") (test-pbe epki4 "Rabbit"))
85102

86103
(define key-pair (generate-key-pair *key:ed25519*))
87104
(define pk (key-pair-private key-pair))

0 commit comments

Comments
 (0)