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. + ! |
Free forum by Nabble | Edit this page |