The Inbox: CryptoCore-rww.6.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: CryptoCore-rww.6.mcz

commits-2
A new version of CryptoCore was added to project The Inbox:
http://source.squeak.org/inbox/CryptoCore-rww.6.mcz

==================== Summary ====================

Name: CryptoCore-rww.6
Author: rww
Time: 28 September 2010, 6:57:27.584 am
UUID: 0bbc592b-767b-7c42-8512-0118c433be8d
Ancestors: CryptoCore-rww.5

added fix to RSAKeyPairGenerator by Denis Kudriashov and refactored DSA and RSA Key Readers

=============== Diff against CryptoCore-rww.5 ===============

Item was changed:
  SystemOrganization addCategory: #CryptoCore!
  SystemOrganization addCategory: #'CryptoCore-Base'!
+ SystemOrganization addCategory: #'CryptoCore-Readers'!
  SystemOrganization addCategory: #'CryptoCore-Utilities'!
  SystemOrganization addCategory: #'CryptoCore-ASN1'!
  SystemOrganization addCategory: #'CryptoCore-ASN1-Objects'!
  SystemOrganization addCategory: #'CryptoCore-ASN1-Types'!
  SystemOrganization addCategory: #'CryptoCore-ASN1-DefinitionModel'!
  SystemOrganization addCategory: #'CryptoCore-PKCS12'!

Item was added:
+ Object subclass: #DSAPrivateKeyFileReader
+ instanceVariableNames: 'bytes decryptedBytes iv password'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'CryptoCore-Readers'!

Item was added:
+ ----- Method: DSAPrivateKeyFileReader classSide>>fromFile: (in category 'as yet unclassified') -----
+ fromFile: filename
+ "(DSAPrivateKeyFileReader fromFile: '/usr/local/ssl/private/dsa.key')"
+ "(DSAPrivateKeyFileReader fromFile: '/Users/slosher/Desktop/squeak/certificates/dsa.key')"
+
+ | fs data |
+ fs := StandardFileStream fileNamed: filename.
+ data := fs contentsOfEntireFile.
+ ^ self new initializeFromFileContents: data.
+ !

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>asASN1Value (in category 'converting') -----
+ asASN1Value
+
+ self decryptedBytes isNil
+ ifTrue: [self decrypt].
+ ^ ASN1Stream decodeBytes: self decryptedBytes
+ !

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>asPrivateKey (in category 'converting') -----
+ asPrivateKey
+
+ | asn1 |
+ asn1 := self asASN1Value.
+ ^ DSAPrivateKey p: (asn1 at: 2) q: (asn1 at: 3) g: (asn1 at: 4) x: (asn1 at: 6).
+ !

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>asPublicKey (in category 'converting') -----
+ asPublicKey
+
+ | asn1 |
+ asn1 := self asASN1Value.
+ ^ DSAPublicKey p: (asn1 at: 2) q: (asn1 at: 3) g: (asn1 at: 4) y: (asn1 at: 5).
+ !

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>bytes (in category 'accessing') -----
+ bytes
+ "Answer the value of bytes"
+
+ ^ bytes!

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>bytes: (in category 'accessing') -----
+ bytes: anObject
+ "Set the value of bytes"
+
+ bytes := anObject!

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>decrypt (in category 'initialization') -----
+ decrypt
+
+ | cipher key block encryptedStream decryptedStream |
+ self password isNil
+ ifTrue: [self password: (FillInTheBlank requestPassword: 'Enter your password')].
+ key := OpenSSLKeyDerivationFunction new
+ derivedKeyFromPassword: self password
+ salt: self iv
+ size: 24.
+ cipher := (TripleDES key: key) cbc initialVector: iv.
+ encryptedStream := self bytes readStream.
+ decryptedStream := ReadWriteStream on: (ByteArray new: encryptedStream size).
+ [encryptedStream atEnd] whileFalse:
+ [block := encryptedStream next: 8.
+ cipher decryptBlock: block.
+ decryptedStream nextPutAll: block].
+ self decryptedBytes: decryptedStream contents.
+ !

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>decryptedBytes (in category 'accessing') -----
+ decryptedBytes
+ "Answer the value of decryptedBytes"
+
+ ^ decryptedBytes!

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>decryptedBytes: (in category 'accessing') -----
+ decryptedBytes: anObject
+ "Set the value of decryptedBytes"
+
+ decryptedBytes := anObject!

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>initializeFromFileContents: (in category 'initialization') -----
+ initializeFromFileContents: data
+
+ | i j theData |
+ i := data indexOfSubCollection: '--BEGIN ' startingAt: 1.
+ i = 0 ifTrue: [self bytes: data asByteArray. ^ self].
+ i := data indexOfSubCollection: 'KEY--' startingAt: i.
+ i := data findAnySubStr: String crlf startingAt: i.
+ j := data findAnySubStr: String crlf startingAt: i + 1.
+ self processProcType: (data copyFrom: i + 1 to: j).
+ i := j.
+ j := data findAnySubStr: String crlf startingAt: i + 1.
+ self processDEKInfo: (data copyFrom: i + 1 to: j).
+ i := j.
+ j := data indexOfSubCollection: '--END ' startingAt: i.
+ theData := (data copyFrom: i to: j)
+ reject: [:c | (c = $-) or: [c isSeparator]].
+ theData := (Base64MimeConverter mimeDecodeToBytes: theData readStream) contents.
+ self bytes: theData.
+ !

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>iv (in category 'accessing') -----
+ iv
+ "Answer the value of iv"
+
+ ^ iv!

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>iv: (in category 'accessing') -----
+ iv: anObject
+ "Set the value of iv"
+
+ iv := anObject!

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>password (in category 'accessing') -----
+ password
+ "Answer the value of password"
+
+ ^ password!

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>password: (in category 'accessing') -----
+ password: anObject
+ "Set the value of password"
+
+ password := anObject!

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>processDEKInfo: (in category 'initialization') -----
+ processDEKInfo: data
+
+ | stream algorithm |
+ stream := data readStream.
+ stream upTo: $:.
+ algorithm := (stream upTo: $,) withBlanksTrimmed.
+ self iv: (Integer readFrom: stream base: 16) asByteArray.
+ !

Item was added:
+ ----- Method: DSAPrivateKeyFileReader>>processProcType: (in category 'initialization') -----
+ processProcType: data
+ !

Item was added:
+ Object subclass: #EuclidAlgorithm
+ instanceVariableNames: 'a b u v gcd'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'CryptoCore-Base'!

Item was added:
+ ----- Method: EuclidAlgorithm classSide>>with:with: (in category 'as yet unclassified') -----
+ with: a with: b
+ ^ self new with: a with: b!

Item was added:
+ ----- Method: EuclidAlgorithm>>doBasicAlgorithm (in category 'as yet unclassified') -----
+ doBasicAlgorithm
+ | u1 a1 b1 q r |
+ u := 1. u1 := 0. a1 := a. b1 := b.
+ [b1 = 0]
+ whileFalse:
+ [q := a1 // b1.
+ r := a1 - (b1 * q).
+ u1 := u - (q * (u := u1)).
+ a1 := b1.
+ b1 := r].
+ gcd := a1.
+ v := b = 0
+ ifTrue: [b]
+ ifFalse: [gcd - (u * a) // b]!

Item was added:
+ ----- Method: EuclidAlgorithm>>firstCoefficient (in category 'as yet unclassified') -----
+ firstCoefficient
+ ^u!

Item was added:
+ ----- Method: EuclidAlgorithm>>gcd (in category 'as yet unclassified') -----
+ gcd
+ ^gcd!

Item was added:
+ ----- Method: EuclidAlgorithm>>lehmer (in category 'as yet unclassified') -----
+ lehmer
+ "For a desciption of the algorithm below for large integers See 'A Course in Computational Algebraic
+ Number Theory' by Henri Cohen"
+
+ "do Preprocessing"
+ | a0 b0 a1 b1 aHat bHat higher aa bb cc dd q t r v1 bcc bdd quoRem e k |
+ b1 := b abs.
+ a1 := a abs max: b1.
+ b1 := a abs min: b1.
+ a0 := a1.
+ b0 := b1. "Initialize elements"
+ u := 1.
+ v1 := 0.
+ aa := 1.
+ bb := 0.
+ cc := 0.
+ dd := 1.
+ higher := 30. "Core.SmallInteger maxVal highBit."
+ ["Are we done yet"
+ b1 class == SmallInteger]
+ whileFalse:
+ [aHat := a1.
+ k := higher - a1 highBit.
+ (aHat bitShift: k) class == SmallInteger
+ ifFalse:
+ [k := k - 1.
+ aHat := aHat bitShift: -1].
+ bHat := b1 bitShift: k.
+
+ ["Test the quotient"
+ bcc := bHat + cc.
+ bcc ~= 0
+ and:
+ [bdd := bHat + dd.
+ bdd ~= 0
+ and:
+ [q := aHat + a1 // bcc.
+ q = (aHat + bb // bdd)]]]
+ whileTrue:
+ ["Euclidean step"
+ aa := cc.
+ cc := aa - (q * aa).
+ bb := dd.
+ dd := bb - (q * bb).
+ aHat := bHat.
+ bHat := aHat - (q * aHat)].
+ bb = 0
+ ifTrue:
+ ["Multi-precision step"
+ quoRem := a1 digitDiv: b1 neg: false.
+ a1 := b1.
+ b1 := quoRem at: 2.
+ u := v1.
+ v1 := u - ((quoRem at: 1)
+ * u)]
+ ifFalse:
+ [t := aa * a1 + (bb * b1).
+ r := cc * a1 + (dd * b1).
+ a1 := t.
+ b1 := r.
+ t := aa * u + (bb * v1).
+ r := cc * u + (dd * v1).
+ u := t.
+ v1 := r]].
+ e := self class with: a1 with: b1.
+ e doBasicAlgorithm.
+ gcd := e gcd.
+ u := u * e firstCoefficient + (v1 * e secondCoefficient).
+ v := b0 = 0
+ ifTrue: [b0]
+ ifFalse: [gcd - (u * a0) // b0].
+ a abs >= b abs
+ ifFalse:
+ ["Postprocess"
+ t := u.
+ u := v.
+ v := t].
+ a < 0 ifTrue: [u := u negated].
+ b < 0 ifTrue: [v := v negated]!

Item was added:
+ ----- Method: EuclidAlgorithm>>run (in category 'as yet unclassified') -----
+ run
+ ((a isKindOf: LargePositiveInteger)
+ and: [b isKindOf: LargePositiveInteger])
+ ifTrue: [self lehmer]
+ ifFalse: [self doBasicAlgorithm]!

Item was added:
+ ----- Method: EuclidAlgorithm>>secondCoefficient (in category 'as yet unclassified') -----
+ secondCoefficient
+ ^ v!

Item was added:
+ ----- Method: EuclidAlgorithm>>with:with: (in category 'as yet unclassified') -----
+ with: numberA with: numberB
+ a := numberA.
+ b := numberB!

Item was changed:
  ----- Method: Pkcs12PrivateKeyFileReader>>decodeSafeBag: (in category 'initialize-release') -----
  decodeSafeBag: safeBag
 
  | asn1 key keyBag cert |
  safeBag bagId oid = '1.2.840.113549.1.12.10.1.1'
  ifTrue: [
  asn1 := ASN1Stream decodeBytes: safeBag bagValue.
  (asn1 at: 1) > 0
+ ifTrue: [key := RSAPublicKey exponent: (asn1 at: 3) modulo: (asn1 at: 1)]
- ifTrue: [key := RSAKey exponent: (asn1 at: 3) modulo: (asn1 at: 1)]
  ifFalse: [key := RSAPrivateKey p: (asn1 at: 5) q: (asn1 at: 6) dP: (asn1 at: 7) dQ: (asn1 at: 8) qInv: (asn1 at: 9)].
  self privateKeys add: key.
  ^ self].
  safeBag bagId oid = '1.2.840.113549.1.12.10.1.2'
  ifTrue: [
  keyBag := safeBag bagValue decryptWithPassword: self password.
  key := keyBag asPrivateKey.
  self privateKeys add: key.
  ^ self].
  safeBag bagId oid = '1.2.840.113549.1.12.10.1.3'
  ifTrue: [
  cert := ASN1Stream
  decodeBytes: safeBag bagValue certValue
  withType: ((ASN1Module name: #x509) find: #Certificate).
  self certs add: cert.
  ^ self].
  self error: 'unknown safe bag: ', safeBag bagId oid.
  !

Item was changed:
  ----- Method: Pkcs8PrivateKeyInfo>>asPrivateKey (in category 'api') -----
  asPrivateKey
 
  | asn1 |
  asn1 := ASN1Stream decodeBytes: self privateKey.
  (asn1 at: 1) > 0
+ ifTrue: [^ RSAPublicKey exponent: (asn1 at: 3) modulo: (asn1 at: 1)]
- ifTrue: [^ RSAKey exponent: (asn1 at: 3) modulo: (asn1 at: 1)]
  ifFalse: [^ RSAPrivateKey
  p: (asn1 at: 5)
  q: (asn1 at: 6)
  dP: (asn1 at: 7)
  dQ: (asn1 at: 8)
  qInv: (asn1 at: 9)]!

Item was removed:
- Object subclass: #RSAKey
- instanceVariableNames: 'exponent modulo'
- classVariableNames: ''
- poolDictionaries: ''
- category: 'CryptoCore'!
-
- !RSAKey commentStamp: '<historical>' prior: 0!
- My instances are RSA algorithms.!

Item was removed:
- ----- Method: RSAKey classSide>>exponent:modulo: (in category 'instance creation') -----
- exponent: anInteger modulo: anotherInteger
- ^ self new setExponent: anInteger modulo: anotherInteger!

Item was removed:
- ----- Method: RSAKey>>bits (in category 'accessing') -----
- bits
- ^ modulo highBit!

Item was removed:
- ----- Method: RSAKey>>crypt: (in category 'process') -----
- crypt: anInteger
- ^ anInteger raisedTo: exponent modulo: modulo!

Item was removed:
- ----- Method: RSAKey>>exponent (in category 'accessing') -----
- exponent
- ^ exponent!

Item was removed:
- ----- Method: RSAKey>>modulo (in category 'accessing') -----
- modulo
- ^ modulo!

Item was removed:
- ----- Method: RSAKey>>setExponent:modulo: (in category 'initialization') -----
- setExponent: anInteger modulo: anotherInteger
- exponent := anInteger.
- modulo := anotherInteger!

Item was removed:
- ----- Method: RSAKey>>v15Decrypt: (in category 'process') -----
- v15Decrypt: aByteArray
-
- | em stream |
- em := self crypt: aByteArray asInteger.
- stream := em asByteArray readStream.
- stream upTo: 16r02.
- stream upTo: 16r00.
- ^ stream upToEnd.
- !

Item was removed:
- ----- Method: RSAKey>>v15Encrypt: (in category 'process') -----
- v15Encrypt: aByteArray
-
- | em k ps |
- k := self modulo asByteArray size.
- ps := SecureRandom new nextBytesNonZero: (k - aByteArray size - 3).
- em := 16r00 asByteArray, 16r02 asByteArray, ps, 16r00 asByteArray, aByteArray.
- ^ (self crypt: em asInteger) asByteArray.
- !

Item was removed:
- ----- Method: RSAKey>>v15SignMessage: (in category 'process') -----
- v15SignMessage: aMessage
-
- ^ self v15SignMessageHash: (
- SHA1 digestInfoAsn1DerEncodingFromMessage: aMessage).
- !

Item was removed:
- ----- Method: RSAKey>>v15SignMessageHash: (in category 'process') -----
- v15SignMessageHash: encodedMsg
-
- | padded toBeSigned |
- padded := ByteArray new: (256 - encodedMsg size - 3) withAll: 255.
- toBeSigned := #(0) asByteArray, #(1) asByteArray, padded, #(0) asByteArray, encodedMsg.
- ^ (self crypt: toBeSigned asInteger) asByteArray.
- !

Item was removed:
- ----- Method: RSAKey>>v15Verify:isSignatureOf: (in category 'process') -----
- v15Verify: aSignature isSignatureOf: aMessage
- "Answer true if the given signature string signs the given message."
-
- ^ self
- v15VerifySignature: aSignature
- ofMessageHash: (
- SHA1 digestInfoAsn1DerEncodingFromMessage: aMessage).
- !

Item was removed:
- ----- Method: RSAKey>>v15VerifySignature:ofMessageHash: (in category 'process') -----
- v15VerifySignature: aSignature ofMessageHash: encodedMsg
- "Answer true if the given signature string signs the given message (a stream or string)."
- "Note: Random numbers are not needed for signature verification; thus, there is no need to call initRandomFromUser before verifying a signature."
-
- | bytes signedMsg |
- bytes := (self crypt: aSignature asInteger) asByteArray.
- signedMsg := bytes readStream upTo: 1; upTo: 0; upToEnd.
- ^ encodedMsg = signedMsg
- !

Item was changed:
  Object subclass: #RSAKeyPairGenerator
+ instanceVariableNames: 'bits p q d dP dQ qInv'
- instanceVariableNames: 'bits p q d'
  classVariableNames: ''
  poolDictionaries: ''
  category: 'CryptoCore'!
 
  !RSAKeyPairGenerator commentStamp: '<historical>' prior: 0!
  My instances generate public/private RSA pairs.!

Item was added:
+ ----- Method: RSAKeyPairGenerator>>dp (in category 'private') -----
+ dp
+
+ ^dP ifNil: [ dP := self d \\ ( self p - 1 ) ]!

Item was added:
+ ----- Method: RSAKeyPairGenerator>>dq (in category 'private') -----
+ dq
+
+ ^dQ ifNil: [ dQ := self d \\ (self q - 1) ]!

Item was changed:
  ----- Method: RSAKeyPairGenerator>>privateKey (in category 'accessing') -----
  privateKey
+ ^ RSAPrivateKey p: self p q: self q dP: self dp dQ: self dq qInv: self qInv!
- ^ RSAKey exponent: self d modulo: self p * self q!

Item was changed:
  ----- Method: RSAKeyPairGenerator>>publicKey (in category 'accessing') -----
  publicKey
+ ^ RSAPublicKey exponent: self e modulo: self p * self q!
- ^ RSAKey exponent: self e modulo: self p * self q!

Item was added:
+ ----- Method: RSAKeyPairGenerator>>qInv (in category 'private') -----
+ qInv
+
+ ^qInv ifNil: [ "qInv = 1 / q mod p"
+ qInv := (EuclidAlgorithm with: q with: p) doBasicAlgorithm; firstCoefficient.
+ qInv < 0 ifTrue: [ qInv := qInv \\ p ].
+ qInv ]!

Item was added:
+ Object subclass: #RSAPrivateKeyFileReader
+ instanceVariableNames: 'bytes decryptedBytes iv password'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'CryptoCore-Readers'!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader classSide>>fromFile: (in category 'instance creation') -----
+ fromFile: filename
+ "(RSAPrivateKeyFileReader fromFile: '/usr/local/ssl/private/CA.key')"
+ "(RSAPrivateKeyFileReader fromFile: '/Users/slosher/Desktop/squeak/certificates/rsa.key')"
+
+ | fs data |
+ fs := StandardFileStream fileNamed: filename.
+ data := fs contentsOfEntireFile.
+ ^ self new initializeFromFileContents: data.
+ !

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>asASN1Value (in category 'converting') -----
+ asASN1Value
+
+ self decryptedBytes isNil
+ ifTrue: [self decrypt].
+ ^ ASN1Stream decodeBytes: self decryptedBytes.
+ !

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>asPrivateKey (in category 'converting') -----
+ asPrivateKey
+
+ | asn1 |
+ asn1 := self asASN1Value.
+ (asn1 at: 1) > 0
+ ifTrue: [^ RSAPublicKey exponent: (asn1 at: 3) modulo: (asn1 at: 1)].
+ ^ RSAPrivateKey p: (asn1 at: 5) q: (asn1 at: 6) dP: (asn1 at: 7) dQ: (asn1 at: 8) qInv: (asn1 at: 9)!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>asPublicKey (in category 'converting') -----
+ asPublicKey
+
+ | asn1 |
+ asn1 := self asASN1Value.
+ ^ RSAPublicKey exponent: (asn1 at: 3) modulo: (asn1 at: 2)!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>bytes (in category 'accessing') -----
+ bytes
+ "Answer the value of bytes"
+
+ ^ bytes!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>bytes: (in category 'accessing') -----
+ bytes: anObject
+ "Set the value of bytes"
+
+ bytes := anObject!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>decrypt (in category 'initialization') -----
+ decrypt
+
+ | cipher key block encryptedStream decryptedStream |
+ self password isNil
+ ifTrue: [self password: (FillInTheBlank requestPassword: 'Enter your password')].
+ key := OpenSSLKeyDerivationFunction new
+ derivedKeyFromPassword: self password
+ salt: self iv
+ size: 24.
+ cipher := (TripleDES key: key) cbc initialVector: iv.
+ encryptedStream := self bytes readStream.
+ decryptedStream := ReadWriteStream on: (ByteArray new: encryptedStream size).
+ [encryptedStream atEnd] whileFalse:
+ [block := encryptedStream next: 8.
+ cipher decryptBlock: block.
+ decryptedStream nextPutAll: block].
+ self decryptedBytes: decryptedStream contents.
+ !

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>decryptedBytes (in category 'accessing') -----
+ decryptedBytes
+ "Answer the value of decryptedBytes"
+
+ ^ decryptedBytes!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>decryptedBytes: (in category 'accessing') -----
+ decryptedBytes: anObject
+ "Set the value of decryptedBytes"
+
+ decryptedBytes := anObject!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>initializeFromFileContents: (in category 'initialization') -----
+ initializeFromFileContents: data
+
+ | i j theData |
+ i := data indexOfSubCollection: '--BEGIN ' startingAt: 1.
+ i = 0 ifTrue: [self derBytes: data asByteArray. ^ self].
+ i := data indexOfSubCollection: 'KEY--' startingAt: i.
+ i := data findAnySubStr: String crlf startingAt: i.
+ j := data findAnySubStr: String crlf startingAt: i + 1.
+ self processProcType: (data copyFrom: i + 1 to: j).
+ i := j.
+ j := data findAnySubStr: String crlf startingAt: i + 1.
+ self processDEKInfo: (data copyFrom: i + 1 to: j).
+ i := j.
+ j := data indexOfSubCollection: '--END ' startingAt: i.
+ theData := (data copyFrom: i to: j)
+ reject: [:c | (c = $-) or: [c isSeparator]].
+ theData := (Base64MimeConverter mimeDecodeToBytes: theData readStream) contents.
+ self bytes: theData.
+ !

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>iv (in category 'accessing') -----
+ iv
+ "Answer the value of iv"
+
+ ^ iv!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>iv: (in category 'accessing') -----
+ iv: anObject
+ "Set the value of iv"
+
+ iv := anObject!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>password (in category 'accessing') -----
+ password
+ "Answer the value of password"
+
+ ^ password!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>password: (in category 'accessing') -----
+ password: anObject
+ "Set the value of password"
+
+ password := anObject!

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>processDEKInfo: (in category 'initialization') -----
+ processDEKInfo: data
+
+ | stream algorithm |
+ stream := data readStream.
+ stream upTo: $:.
+ algorithm := (stream upTo: $,) withBlanksTrimmed.
+ self iv: (Integer readFrom: stream base: 16) asByteArray.
+ !

Item was added:
+ ----- Method: RSAPrivateKeyFileReader>>processProcType: (in category 'initialization') -----
+ processProcType: data
+ !

Item was added:
+ Object subclass: #RSAPublicKey
+ instanceVariableNames: 'exponent modulo'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'CryptoCore'!
+
+ !RSAPublicKey commentStamp: '<historical>' prior: 0!
+ My instances are RSA algorithms.!

Item was added:
+ ----- Method: RSAPublicKey classSide>>exponent:modulo: (in category 'instance creation') -----
+ exponent: anInteger modulo: anotherInteger
+ ^ self new setExponent: anInteger modulo: anotherInteger!

Item was added:
+ ----- Method: RSAPublicKey>>bits (in category 'accessing') -----
+ bits
+ ^ modulo highBit!

Item was added:
+ ----- Method: RSAPublicKey>>crypt: (in category 'process') -----
+ crypt: anInteger
+ ^ anInteger raisedTo: exponent modulo: modulo!

Item was added:
+ ----- Method: RSAPublicKey>>exponent (in category 'accessing') -----
+ exponent
+ ^ exponent!

Item was added:
+ ----- Method: RSAPublicKey>>modulo (in category 'accessing') -----
+ modulo
+ ^ modulo!

Item was added:
+ ----- Method: RSAPublicKey>>setExponent:modulo: (in category 'initialization') -----
+ setExponent: anInteger modulo: anotherInteger
+ exponent := anInteger.
+ modulo := anotherInteger!

Item was added:
+ ----- Method: RSAPublicKey>>v15Decrypt: (in category 'process') -----
+ v15Decrypt: aByteArray
+
+ | em stream |
+ em := self crypt: aByteArray asInteger.
+ stream := em asByteArray readStream.
+ stream upTo: 16r02.
+ stream upTo: 16r00.
+ ^ stream upToEnd.
+ !

Item was added:
+ ----- Method: RSAPublicKey>>v15Encrypt: (in category 'process') -----
+ v15Encrypt: aByteArray
+
+ | em k ps |
+ k := self modulo asByteArray size.
+ ps := SecureRandom new nextBytesNonZero: (k - aByteArray size - 3).
+ em := 16r00 asByteArray, 16r02 asByteArray, ps, 16r00 asByteArray, aByteArray.
+ ^ (self crypt: em asInteger) asByteArray.
+ !

Item was added:
+ ----- Method: RSAPublicKey>>v15SignMessage: (in category 'process') -----
+ v15SignMessage: aMessage
+
+ ^ self v15SignMessageHash: (
+ SHA1 digestInfoAsn1DerEncodingFromMessage: aMessage).
+ !

Item was added:
+ ----- Method: RSAPublicKey>>v15SignMessageHash: (in category 'process') -----
+ v15SignMessageHash: encodedMsg
+
+ | padded toBeSigned |
+ padded := ByteArray new: (256 - encodedMsg size - 3) withAll: 255.
+ toBeSigned := #(0) asByteArray, #(1) asByteArray, padded, #(0) asByteArray, encodedMsg.
+ ^ (self crypt: toBeSigned asInteger) asByteArray.
+ !

Item was added:
+ ----- Method: RSAPublicKey>>v15Verify:isSignatureOf: (in category 'process') -----
+ v15Verify: aSignature isSignatureOf: aMessage
+ "Answer true if the given signature string signs the given message."
+
+ ^ self
+ v15VerifySignature: aSignature
+ ofMessageHash: (
+ SHA1 digestInfoAsn1DerEncodingFromMessage: aMessage).
+ !

Item was added:
+ ----- Method: RSAPublicKey>>v15VerifySignature:ofMessageHash: (in category 'process') -----
+ v15VerifySignature: aSignature ofMessageHash: encodedMsg
+ "Answer true if the given signature string signs the given message (a stream or string)."
+ "Note: Random numbers are not needed for signature verification; thus, there is no need to call initRandomFromUser before verifying a signature."
+
+ | bytes signedMsg |
+ bytes := (self crypt: aSignature asInteger) asByteArray.
+ signedMsg := bytes readStream upTo: 1; upTo: 0; upToEnd.
+ ^ encodedMsg = signedMsg
+ !

Item was added:
+ Object subclass: #RSAPublicKeyFileReader
+ instanceVariableNames: 'bytes'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'CryptoCore-Readers'!

Item was added:
+ ----- Method: RSAPublicKeyFileReader classSide>>fromFile: (in category 'instance creation') -----
+ fromFile: filename
+ "(RSAPrivateKeyFileReader fromFile: '/usr/local/ssl/private/CA.key')"
+ "(RSAPrivateKeyFileReader fromFile: '/Users/slosher/Desktop/squeak/certificates/rsa.key')"
+
+ | fs data |
+ fs := StandardFileStream fileNamed: filename.
+ data := fs contentsOfEntireFile.
+ ^ self new initializeFromFileContents: data.
+ !

Item was added:
+ ----- Method: RSAPublicKeyFileReader>>asASN1Value (in category 'converting') -----
+ asASN1Value
+
+ | asn1 |
+ asn1 := ASN1Stream decodeBytes: self bytes.
+ ^ ASN1Stream decodeBytes: (asn1 at: 2) bytes!

Item was added:
+ ----- Method: RSAPublicKeyFileReader>>asPublicKey (in category 'converting') -----
+ asPublicKey
+
+ | asn1 |
+ asn1 := self asASN1Value.
+ ^ RSAPublicKey exponent: (asn1 at: 2) modulo: (asn1 at: 1)!

Item was added:
+ ----- Method: RSAPublicKeyFileReader>>bytes (in category 'accessing') -----
+ bytes
+ "Answer the value of bytes"
+
+ ^ bytes!

Item was added:
+ ----- Method: RSAPublicKeyFileReader>>bytes: (in category 'accessing') -----
+ bytes: anObject
+ "Set the value of bytes"
+
+ bytes := anObject!

Item was added:
+ ----- Method: RSAPublicKeyFileReader>>initializeFromFileContents: (in category 'initialize-release') -----
+ initializeFromFileContents: data
+
+ | i j theData |
+ i := data indexOfSubCollection: '--BEGIN ' startingAt: 1.
+ i = 0 ifTrue: [self derBytes: data asByteArray. ^ self].
+ i := data indexOfSubCollection: 'KEY--' startingAt: i.
+ i := data findAnySubStr: String crlf startingAt: i.
+ j := data findAnySubStr: String crlf startingAt: i + 1.
+ " self processProcType: (data copyFrom: i + 1 to: j)."
+ i := j.
+ j := data findAnySubStr: String crlf startingAt: i + 1.
+ " self processDEKInfo: (data copyFrom: i + 1 to: j)."
+ i := j.
+ j := data indexOfSubCollection: '--END ' startingAt: i.
+ theData := (data copyFrom: i to: j)
+ reject: [:c | (c = $-) or: [c isSeparator]].
+ theData := (Base64MimeConverter mimeDecodeToBytes: theData readStream) contents.
+ self bytes: theData.
+ !