Module: RSA::OAEP

Extended by:
OAEP
Included in:
OAEP
Defined in:
lib/rack/shibboleth/rsa_ext.rb

Defined Under Namespace

Classes: DecodeError

Constant Summary collapse

HLEN =

The algorithms below need the HLEN variable. This is the length of the hashes generated by the hashing function. For now, this only supports SHA1 as the hashing function, and this has a hash length of 20

20

Instance Method Summary collapse

Instance Method Details

#decode(k, c, p = '') ⇒ String

Performs the rsa-oaep-mgf1 decrypt algorithm. This is specified in section 7.1.2 of www.ietf.org/rfc/rfc2437.txt.

This implementation assumes that the sha1 hashing algorithm was used.

Parameters:

  • k (RSA::Key)

    the private key whose public key was used to encrypt the data

  • c (String)

    a string of raw bytes representing the text to be decoded

  • p (String) (defaults to: '')

    the options which were used in the original encoding of the string. By default this is the empty string.

Returns:

  • (String)

    the decoded string of bytes

Raises:

  • (DecodeError)

    If decoding cannot occur, an error is raised


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rack/shibboleth/rsa_ext.rb', line 32

def decode k, c, p = ''
  # First, generate how many bytes the key's modulus is
  n = k.modulus
  bytes = 0
  while n > 0
    bytes += 1
    n /= 2
  end
  bytes /= 8

  raise DecodeError, 'input is wrong length!' unless c.length == bytes

  enc = RSA::PKCS1.os2ip c
  m   = RSA::PKCS1.rsadp k, enc
  em  = RSA::PKCS1.i2osp m, bytes - 1

  eme_decode em, p
end

#eme_decode(em, p = '') ⇒ String

Decodes the encrypted message as specified by the algorithm listed on www.ietf.org/rfc/rfc2437.txt in section 9.1.1.2

Parameters:

  • em (String)

    the encoded message that needs to be decoded

  • p (String) (defaults to: '')

    the flags used in the original encoding scheme.

Returns:

  • (String)

    the decoded byte string of the supplied message

Raises:

  • (DecodeError)

    if decoding goes awry or the message does not pass sanity checks during decoding


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/rack/shibboleth/rsa_ext.rb', line 60

def eme_decode em, p = ''
  raise DecodeError, 'message is too short!' if em.length < HLEN * 2 + 1

  maskedSeed = em[0...HLEN]
  maskedDB   = em[HLEN..-1]
  seedMask   = mgf1 maskedDB, HLEN
  seed       = xor maskedSeed, seedMask
  dbMask     = mgf1 seed, em.size - HLEN
  db         = xor maskedDB, dbMask
  pHash      = Digest::SHA1.digest p

  ind = db.index("\x01", HLEN)
  raise DecodeError, 'message is invalid!' if ind.nil?

  pHash2 = db[0...HLEN]
  ps     = db[HLEN...ind]
  m      = db[(ind + 1)..-1]

  raise DecodeError, 'message is invalid!' unless ps.bytes.all?(&:zero?)
  raise DecodeError, "specified p = #{p.inspect} is wrong!" unless pHash2 == pHash

  m
end

#mgf1(z, l) ⇒ String

Defined in seciton 10.2.1 of www.ietf.org/rfc/rfc2437.txt, this is the mask generation function used in the eme_decode function

Parameters:

  • z (String)

    this is the seed which the mask function runs off of

  • l (Integer)

    the desired length of the resultant hash

Returns:

  • (String)

    the mask generated


91
92
93
94
95
96
97
98
99
# File 'lib/rack/shibboleth/rsa_ext.rb', line 91

def mgf1 z, l
  t = ''

  (0..(l / HLEN)).each{ |i|
    t += Digest::SHA1.digest(z + RSA::PKCS1.i2osp(i, 4))
  }

  t[0...l]
end