mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-04-08 17:06:09 +00:00
pairing works!
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
FB290DC419B2E98F004C83CF /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290DC319B2E98F004C83CF /* libxml2.dylib */; };
|
||||
FB290E7919B37D81004C83CF /* MainFrame-iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7819B37D81004C83CF /* MainFrame-iPad.storyboard */; };
|
||||
FB290E7B19B38036004C83CF /* MainFrame-iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */; };
|
||||
FB63FCF219F43EBC00227761 /* PairManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FB63FCF119F43EBC00227761 /* PairManager.m */; };
|
||||
FB7E794419C8B71B00A15F68 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FB7E794319C8B71B00A15F68 /* libiconv.dylib */; };
|
||||
FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F119EDB08B00929691 /* MDNSManager.m */; };
|
||||
FBAB29F619EDE0F800929691 /* Computer.m in Sources */ = {isa = PBXBuildFile; fileRef = FBAB29F519EDE0F800929691 /* Computer.m */; };
|
||||
@@ -117,6 +118,8 @@
|
||||
FB290DC319B2E98F004C83CF /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
|
||||
FB290E7819B37D81004C83CF /* MainFrame-iPad.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "MainFrame-iPad.storyboard"; sourceTree = SOURCE_ROOT; };
|
||||
FB290E7A19B38036004C83CF /* MainFrame-iPhone.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "MainFrame-iPhone.storyboard"; sourceTree = SOURCE_ROOT; };
|
||||
FB63FCF019F43EBC00227761 /* PairManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PairManager.h; sourceTree = "<group>"; };
|
||||
FB63FCF119F43EBC00227761 /* PairManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PairManager.m; sourceTree = "<group>"; };
|
||||
FB7E794319C8B71B00A15F68 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = usr/lib/libiconv.dylib; sourceTree = SDKROOT; };
|
||||
FBAB29F119EDB08B00929691 /* MDNSManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDNSManager.m; sourceTree = "<group>"; };
|
||||
FBAB29F319EDB0C400929691 /* MDNSManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDNSManager.h; sourceTree = "<group>"; };
|
||||
@@ -206,101 +209,6 @@
|
||||
FBCC0E9919EF9703009729EB /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libssl.a; sourceTree = "<group>"; };
|
||||
FBCC0E9C19F00659009729EB /* mkcert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mkcert.c; sourceTree = "<group>"; };
|
||||
FBCC0E9E19F00697009729EB /* mkcert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mkcert.h; sourceTree = "<group>"; };
|
||||
FBD8B3FD19C906230032E027 /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libavcodec.a; sourceTree = "<group>"; };
|
||||
FBD8B3FE19C906230032E027 /* libavdevice.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libavdevice.a; sourceTree = "<group>"; };
|
||||
FBD8B3FF19C906230032E027 /* libavfilter.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libavfilter.a; sourceTree = "<group>"; };
|
||||
FBD8B40019C906230032E027 /* libavformat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libavformat.a; sourceTree = "<group>"; };
|
||||
FBD8B40119C906230032E027 /* libavresample.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libavresample.a; sourceTree = "<group>"; };
|
||||
FBD8B40219C906230032E027 /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libavutil.a; sourceTree = "<group>"; };
|
||||
FBD8B40319C906230032E027 /* libswresample.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libswresample.a; sourceTree = "<group>"; };
|
||||
FBD8B40419C906230032E027 /* libswscale.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libswscale.a; sourceTree = "<group>"; };
|
||||
FBD8B40F19C9064B0032E027 /* avcodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avcodec.h; sourceTree = "<group>"; };
|
||||
FBD8B41019C9064B0032E027 /* avfft.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avfft.h; sourceTree = "<group>"; };
|
||||
FBD8B41119C9064B0032E027 /* dv_profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dv_profile.h; sourceTree = "<group>"; };
|
||||
FBD8B41219C9064B0032E027 /* dxva2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dxva2.h; sourceTree = "<group>"; };
|
||||
FBD8B41319C9064B0032E027 /* old_codec_ids.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = old_codec_ids.h; sourceTree = "<group>"; };
|
||||
FBD8B41419C9064B0032E027 /* vaapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vaapi.h; sourceTree = "<group>"; };
|
||||
FBD8B41519C9064B0032E027 /* vda.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vda.h; sourceTree = "<group>"; };
|
||||
FBD8B41619C9064B0032E027 /* vdpau.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vdpau.h; sourceTree = "<group>"; };
|
||||
FBD8B41719C9064B0032E027 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
||||
FBD8B41819C9064B0032E027 /* xvmc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xvmc.h; sourceTree = "<group>"; };
|
||||
FBD8B41A19C9064B0032E027 /* avdevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avdevice.h; sourceTree = "<group>"; };
|
||||
FBD8B41B19C9064B0032E027 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
||||
FBD8B41D19C9064B0032E027 /* asrc_abuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = asrc_abuffer.h; sourceTree = "<group>"; };
|
||||
FBD8B41E19C9064B0032E027 /* avcodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avcodec.h; sourceTree = "<group>"; };
|
||||
FBD8B41F19C9064B0032E027 /* avfilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avfilter.h; sourceTree = "<group>"; };
|
||||
FBD8B42019C9064B0032E027 /* avfiltergraph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avfiltergraph.h; sourceTree = "<group>"; };
|
||||
FBD8B42119C9064B0032E027 /* buffersink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffersink.h; sourceTree = "<group>"; };
|
||||
FBD8B42219C9064B0032E027 /* buffersrc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffersrc.h; sourceTree = "<group>"; };
|
||||
FBD8B42319C9064B0032E027 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
||||
FBD8B42519C9064B0032E027 /* avformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avformat.h; sourceTree = "<group>"; };
|
||||
FBD8B42619C9064B0032E027 /* avio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avio.h; sourceTree = "<group>"; };
|
||||
FBD8B42719C9064B0032E027 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
||||
FBD8B42919C9064B0032E027 /* avresample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avresample.h; sourceTree = "<group>"; };
|
||||
FBD8B42A19C9064B0032E027 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
||||
FBD8B42C19C9064B0032E027 /* adler32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = adler32.h; sourceTree = "<group>"; };
|
||||
FBD8B42D19C9064B0032E027 /* aes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aes.h; sourceTree = "<group>"; };
|
||||
FBD8B42E19C9064B0032E027 /* attributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attributes.h; sourceTree = "<group>"; };
|
||||
FBD8B42F19C9064B0032E027 /* audio_fifo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audio_fifo.h; sourceTree = "<group>"; };
|
||||
FBD8B43019C9064B0032E027 /* audioconvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audioconvert.h; sourceTree = "<group>"; };
|
||||
FBD8B43119C9064B0032E027 /* avassert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avassert.h; sourceTree = "<group>"; };
|
||||
FBD8B43219C9064B0032E027 /* avconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avconfig.h; sourceTree = "<group>"; };
|
||||
FBD8B43319C9064B0032E027 /* avstring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avstring.h; sourceTree = "<group>"; };
|
||||
FBD8B43419C9064B0032E027 /* avutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avutil.h; sourceTree = "<group>"; };
|
||||
FBD8B43519C9064B0032E027 /* base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = base64.h; sourceTree = "<group>"; };
|
||||
FBD8B43619C9064B0032E027 /* blowfish.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blowfish.h; sourceTree = "<group>"; };
|
||||
FBD8B43719C9064B0032E027 /* bprint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bprint.h; sourceTree = "<group>"; };
|
||||
FBD8B43819C9064B0032E027 /* bswap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bswap.h; sourceTree = "<group>"; };
|
||||
FBD8B43919C9064B0032E027 /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = "<group>"; };
|
||||
FBD8B43A19C9064B0032E027 /* channel_layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = channel_layout.h; sourceTree = "<group>"; };
|
||||
FBD8B43B19C9064B0032E027 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
|
||||
FBD8B43C19C9064B0032E027 /* cpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpu.h; sourceTree = "<group>"; };
|
||||
FBD8B43D19C9064B0032E027 /* crc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crc.h; sourceTree = "<group>"; };
|
||||
FBD8B43E19C9064B0032E027 /* dict.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dict.h; sourceTree = "<group>"; };
|
||||
FBD8B43F19C9064B0032E027 /* display.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = display.h; sourceTree = "<group>"; };
|
||||
FBD8B44019C9064B0032E027 /* downmix_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = downmix_info.h; sourceTree = "<group>"; };
|
||||
FBD8B44119C9064B0032E027 /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = error.h; sourceTree = "<group>"; };
|
||||
FBD8B44219C9064B0032E027 /* eval.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = eval.h; sourceTree = "<group>"; };
|
||||
FBD8B44319C9064B0032E027 /* ffversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffversion.h; sourceTree = "<group>"; };
|
||||
FBD8B44419C9064B0032E027 /* fifo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fifo.h; sourceTree = "<group>"; };
|
||||
FBD8B44519C9064B0032E027 /* file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file.h; sourceTree = "<group>"; };
|
||||
FBD8B44619C9064B0032E027 /* frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = frame.h; sourceTree = "<group>"; };
|
||||
FBD8B44719C9064B0032E027 /* hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hash.h; sourceTree = "<group>"; };
|
||||
FBD8B44819C9064B0032E027 /* hmac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hmac.h; sourceTree = "<group>"; };
|
||||
FBD8B44919C9064B0032E027 /* imgutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgutils.h; sourceTree = "<group>"; };
|
||||
FBD8B44A19C9064B0032E027 /* intfloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intfloat.h; sourceTree = "<group>"; };
|
||||
FBD8B44B19C9064B0032E027 /* intfloat_readwrite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intfloat_readwrite.h; sourceTree = "<group>"; };
|
||||
FBD8B44C19C9064B0032E027 /* intreadwrite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intreadwrite.h; sourceTree = "<group>"; };
|
||||
FBD8B44D19C9064B0032E027 /* lfg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lfg.h; sourceTree = "<group>"; };
|
||||
FBD8B44E19C9064B0032E027 /* log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = log.h; sourceTree = "<group>"; };
|
||||
FBD8B44F19C9064B0032E027 /* macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macros.h; sourceTree = "<group>"; };
|
||||
FBD8B45019C9064B0032E027 /* mathematics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mathematics.h; sourceTree = "<group>"; };
|
||||
FBD8B45119C9064B0032E027 /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = "<group>"; };
|
||||
FBD8B45219C9064B0032E027 /* mem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mem.h; sourceTree = "<group>"; };
|
||||
FBD8B45319C9064B0032E027 /* murmur3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = murmur3.h; sourceTree = "<group>"; };
|
||||
FBD8B45419C9064B0032E027 /* old_pix_fmts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = old_pix_fmts.h; sourceTree = "<group>"; };
|
||||
FBD8B45519C9064B0032E027 /* opt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opt.h; sourceTree = "<group>"; };
|
||||
FBD8B45619C9064B0032E027 /* parseutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parseutils.h; sourceTree = "<group>"; };
|
||||
FBD8B45719C9064B0032E027 /* pixdesc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pixdesc.h; sourceTree = "<group>"; };
|
||||
FBD8B45819C9064B0032E027 /* pixfmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pixfmt.h; sourceTree = "<group>"; };
|
||||
FBD8B45919C9064B0032E027 /* random_seed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = random_seed.h; sourceTree = "<group>"; };
|
||||
FBD8B45A19C9064B0032E027 /* rational.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rational.h; sourceTree = "<group>"; };
|
||||
FBD8B45B19C9064B0032E027 /* replaygain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = replaygain.h; sourceTree = "<group>"; };
|
||||
FBD8B45C19C9064B0032E027 /* ripemd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ripemd.h; sourceTree = "<group>"; };
|
||||
FBD8B45D19C9064B0032E027 /* samplefmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = samplefmt.h; sourceTree = "<group>"; };
|
||||
FBD8B45E19C9064B0032E027 /* sha.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sha.h; sourceTree = "<group>"; };
|
||||
FBD8B45F19C9064B0032E027 /* sha512.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sha512.h; sourceTree = "<group>"; };
|
||||
FBD8B46019C9064B0032E027 /* stereo3d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stereo3d.h; sourceTree = "<group>"; };
|
||||
FBD8B46119C9064B0032E027 /* threadmessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = threadmessage.h; sourceTree = "<group>"; };
|
||||
FBD8B46219C9064B0032E027 /* time.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = time.h; sourceTree = "<group>"; };
|
||||
FBD8B46319C9064B0032E027 /* timecode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timecode.h; sourceTree = "<group>"; };
|
||||
FBD8B46419C9064B0032E027 /* timestamp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timestamp.h; sourceTree = "<group>"; };
|
||||
FBD8B46519C9064B0032E027 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
||||
FBD8B46619C9064B0032E027 /* xtea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xtea.h; sourceTree = "<group>"; };
|
||||
FBD8B46819C9064B0032E027 /* swresample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = swresample.h; sourceTree = "<group>"; };
|
||||
FBD8B46919C9064B0032E027 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
||||
FBD8B46B19C9064B0032E027 /* swscale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = swscale.h; sourceTree = "<group>"; };
|
||||
FBD8B46C19C9064B0032E027 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -386,6 +294,8 @@
|
||||
FB290CF919B2C406004C83CF /* Limelight */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FB63FCF019F43EBC00227761 /* PairManager.h */,
|
||||
FB63FCF119F43EBC00227761 /* PairManager.m */,
|
||||
FB290D3019B2C6E3004C83CF /* Video */,
|
||||
FB290D2619B2C6E3004C83CF /* Connection.h */,
|
||||
FB290D2719B2C6E3004C83CF /* Connection.m */,
|
||||
@@ -458,7 +368,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBCC0E4919EF9703009729EB /* openssl */,
|
||||
FB2C87FA19B8F0B300F7655B /* FFmpeg */,
|
||||
FB290DA719B2C814004C83CF /* limelight-common */,
|
||||
FB290DAC19B2C814004C83CF /* opus */,
|
||||
);
|
||||
@@ -526,15 +435,6 @@
|
||||
path = lib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FB2C87FA19B8F0B300F7655B /* FFmpeg */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B40D19C9064B0032E027 /* include */,
|
||||
FBD8B3FC19C906230032E027 /* lib */,
|
||||
);
|
||||
path = FFmpeg;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBC8622F19F346A60087327B /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -651,179 +551,6 @@
|
||||
path = lib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B3FC19C906230032E027 /* lib */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B3FD19C906230032E027 /* libavcodec.a */,
|
||||
FBD8B3FE19C906230032E027 /* libavdevice.a */,
|
||||
FBD8B3FF19C906230032E027 /* libavfilter.a */,
|
||||
FBD8B40019C906230032E027 /* libavformat.a */,
|
||||
FBD8B40119C906230032E027 /* libavresample.a */,
|
||||
FBD8B40219C906230032E027 /* libavutil.a */,
|
||||
FBD8B40319C906230032E027 /* libswresample.a */,
|
||||
FBD8B40419C906230032E027 /* libswscale.a */,
|
||||
);
|
||||
path = lib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B40D19C9064B0032E027 /* include */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B40E19C9064B0032E027 /* libavcodec */,
|
||||
FBD8B41919C9064B0032E027 /* libavdevice */,
|
||||
FBD8B41C19C9064B0032E027 /* libavfilter */,
|
||||
FBD8B42419C9064B0032E027 /* libavformat */,
|
||||
FBD8B42819C9064B0032E027 /* libavresample */,
|
||||
FBD8B42B19C9064B0032E027 /* libavutil */,
|
||||
FBD8B46719C9064B0032E027 /* libswresample */,
|
||||
FBD8B46A19C9064B0032E027 /* libswscale */,
|
||||
);
|
||||
path = include;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B40E19C9064B0032E027 /* libavcodec */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B40F19C9064B0032E027 /* avcodec.h */,
|
||||
FBD8B41019C9064B0032E027 /* avfft.h */,
|
||||
FBD8B41119C9064B0032E027 /* dv_profile.h */,
|
||||
FBD8B41219C9064B0032E027 /* dxva2.h */,
|
||||
FBD8B41319C9064B0032E027 /* old_codec_ids.h */,
|
||||
FBD8B41419C9064B0032E027 /* vaapi.h */,
|
||||
FBD8B41519C9064B0032E027 /* vda.h */,
|
||||
FBD8B41619C9064B0032E027 /* vdpau.h */,
|
||||
FBD8B41719C9064B0032E027 /* version.h */,
|
||||
FBD8B41819C9064B0032E027 /* xvmc.h */,
|
||||
);
|
||||
path = libavcodec;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B41919C9064B0032E027 /* libavdevice */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B41A19C9064B0032E027 /* avdevice.h */,
|
||||
FBD8B41B19C9064B0032E027 /* version.h */,
|
||||
);
|
||||
path = libavdevice;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B41C19C9064B0032E027 /* libavfilter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B41D19C9064B0032E027 /* asrc_abuffer.h */,
|
||||
FBD8B41E19C9064B0032E027 /* avcodec.h */,
|
||||
FBD8B41F19C9064B0032E027 /* avfilter.h */,
|
||||
FBD8B42019C9064B0032E027 /* avfiltergraph.h */,
|
||||
FBD8B42119C9064B0032E027 /* buffersink.h */,
|
||||
FBD8B42219C9064B0032E027 /* buffersrc.h */,
|
||||
FBD8B42319C9064B0032E027 /* version.h */,
|
||||
);
|
||||
path = libavfilter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B42419C9064B0032E027 /* libavformat */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B42519C9064B0032E027 /* avformat.h */,
|
||||
FBD8B42619C9064B0032E027 /* avio.h */,
|
||||
FBD8B42719C9064B0032E027 /* version.h */,
|
||||
);
|
||||
path = libavformat;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B42819C9064B0032E027 /* libavresample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B42919C9064B0032E027 /* avresample.h */,
|
||||
FBD8B42A19C9064B0032E027 /* version.h */,
|
||||
);
|
||||
path = libavresample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B42B19C9064B0032E027 /* libavutil */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B42C19C9064B0032E027 /* adler32.h */,
|
||||
FBD8B42D19C9064B0032E027 /* aes.h */,
|
||||
FBD8B42E19C9064B0032E027 /* attributes.h */,
|
||||
FBD8B42F19C9064B0032E027 /* audio_fifo.h */,
|
||||
FBD8B43019C9064B0032E027 /* audioconvert.h */,
|
||||
FBD8B43119C9064B0032E027 /* avassert.h */,
|
||||
FBD8B43219C9064B0032E027 /* avconfig.h */,
|
||||
FBD8B43319C9064B0032E027 /* avstring.h */,
|
||||
FBD8B43419C9064B0032E027 /* avutil.h */,
|
||||
FBD8B43519C9064B0032E027 /* base64.h */,
|
||||
FBD8B43619C9064B0032E027 /* blowfish.h */,
|
||||
FBD8B43719C9064B0032E027 /* bprint.h */,
|
||||
FBD8B43819C9064B0032E027 /* bswap.h */,
|
||||
FBD8B43919C9064B0032E027 /* buffer.h */,
|
||||
FBD8B43A19C9064B0032E027 /* channel_layout.h */,
|
||||
FBD8B43B19C9064B0032E027 /* common.h */,
|
||||
FBD8B43C19C9064B0032E027 /* cpu.h */,
|
||||
FBD8B43D19C9064B0032E027 /* crc.h */,
|
||||
FBD8B43E19C9064B0032E027 /* dict.h */,
|
||||
FBD8B43F19C9064B0032E027 /* display.h */,
|
||||
FBD8B44019C9064B0032E027 /* downmix_info.h */,
|
||||
FBD8B44119C9064B0032E027 /* error.h */,
|
||||
FBD8B44219C9064B0032E027 /* eval.h */,
|
||||
FBD8B44319C9064B0032E027 /* ffversion.h */,
|
||||
FBD8B44419C9064B0032E027 /* fifo.h */,
|
||||
FBD8B44519C9064B0032E027 /* file.h */,
|
||||
FBD8B44619C9064B0032E027 /* frame.h */,
|
||||
FBD8B44719C9064B0032E027 /* hash.h */,
|
||||
FBD8B44819C9064B0032E027 /* hmac.h */,
|
||||
FBD8B44919C9064B0032E027 /* imgutils.h */,
|
||||
FBD8B44A19C9064B0032E027 /* intfloat.h */,
|
||||
FBD8B44B19C9064B0032E027 /* intfloat_readwrite.h */,
|
||||
FBD8B44C19C9064B0032E027 /* intreadwrite.h */,
|
||||
FBD8B44D19C9064B0032E027 /* lfg.h */,
|
||||
FBD8B44E19C9064B0032E027 /* log.h */,
|
||||
FBD8B44F19C9064B0032E027 /* macros.h */,
|
||||
FBD8B45019C9064B0032E027 /* mathematics.h */,
|
||||
FBD8B45119C9064B0032E027 /* md5.h */,
|
||||
FBD8B45219C9064B0032E027 /* mem.h */,
|
||||
FBD8B45319C9064B0032E027 /* murmur3.h */,
|
||||
FBD8B45419C9064B0032E027 /* old_pix_fmts.h */,
|
||||
FBD8B45519C9064B0032E027 /* opt.h */,
|
||||
FBD8B45619C9064B0032E027 /* parseutils.h */,
|
||||
FBD8B45719C9064B0032E027 /* pixdesc.h */,
|
||||
FBD8B45819C9064B0032E027 /* pixfmt.h */,
|
||||
FBD8B45919C9064B0032E027 /* random_seed.h */,
|
||||
FBD8B45A19C9064B0032E027 /* rational.h */,
|
||||
FBD8B45B19C9064B0032E027 /* replaygain.h */,
|
||||
FBD8B45C19C9064B0032E027 /* ripemd.h */,
|
||||
FBD8B45D19C9064B0032E027 /* samplefmt.h */,
|
||||
FBD8B45E19C9064B0032E027 /* sha.h */,
|
||||
FBD8B45F19C9064B0032E027 /* sha512.h */,
|
||||
FBD8B46019C9064B0032E027 /* stereo3d.h */,
|
||||
FBD8B46119C9064B0032E027 /* threadmessage.h */,
|
||||
FBD8B46219C9064B0032E027 /* time.h */,
|
||||
FBD8B46319C9064B0032E027 /* timecode.h */,
|
||||
FBD8B46419C9064B0032E027 /* timestamp.h */,
|
||||
FBD8B46519C9064B0032E027 /* version.h */,
|
||||
FBD8B46619C9064B0032E027 /* xtea.h */,
|
||||
);
|
||||
path = libavutil;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B46719C9064B0032E027 /* libswresample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B46819C9064B0032E027 /* swresample.h */,
|
||||
FBD8B46919C9064B0032E027 /* version.h */,
|
||||
);
|
||||
path = libswresample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FBD8B46A19C9064B0032E027 /* libswscale */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FBD8B46B19C9064B0032E027 /* swscale.h */,
|
||||
FBD8B46C19C9064B0032E027 /* version.h */,
|
||||
);
|
||||
path = libswscale;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -950,6 +677,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FBAB29FC19EE13AA00929691 /* CryptoManager.m in Sources */,
|
||||
FB63FCF219F43EBC00227761 /* PairManager.m in Sources */,
|
||||
98A03B5019F3598400861ACA /* VideoDecoderRenderer.m in Sources */,
|
||||
FBAB29F219EDB08B00929691 /* MDNSManager.m in Sources */,
|
||||
FBC8622D19F0BEFB0087327B /* HttpManager.m in Sources */,
|
||||
|
||||
@@ -15,4 +15,13 @@
|
||||
+ (NSData*) readCertFromFile;
|
||||
+ (NSData*) readKeyFromFile;
|
||||
+ (NSData*) readP12FromFile;
|
||||
+ (NSData*) getSignatureFromCert:(NSData*)cert;
|
||||
|
||||
- (NSData*) createAESKeyFromSalt:(NSData*)saltedPIN;
|
||||
- (NSData*) SHA1HashData:(NSData*)data;
|
||||
- (NSData*) aesEncrypt:(NSData*)data withKey:(NSData*)key;
|
||||
- (NSData*) aesDecrypt:(NSData*)data withKey:(NSData*)key;
|
||||
- (bool) verifySignature:(NSData *)data withSignature:(NSData*)signature andCert:(NSData*)cert;
|
||||
- (NSData*) signData:(NSData*)data withKey:(NSData*)key;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,7 +10,135 @@
|
||||
#import "mkcert.h"
|
||||
#import <AdSupport/ASIdentifierManager.h>
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
@implementation CryptoManager
|
||||
static const int SHA1_DIGEST_LENGTH = 20;
|
||||
|
||||
- (NSData*) createAESKeyFromSalt:(NSData*)saltedPIN {
|
||||
return [[self SHA1HashData:saltedPIN] subdataWithRange:NSMakeRange(0, 16)];
|
||||
}
|
||||
|
||||
- (NSData*) SHA1HashData:(NSData*)data {
|
||||
unsigned char sha1[SHA1_DIGEST_LENGTH];
|
||||
SHA1([data bytes], [data length], sha1);
|
||||
NSData* bytes = [NSData dataWithBytes:sha1 length:20];
|
||||
return bytes;
|
||||
}
|
||||
|
||||
- (NSData*) aesEncrypt:(NSData*)data withKey:(NSData*)key {
|
||||
AES_KEY aesKey;
|
||||
AES_set_encrypt_key([key bytes], 128, &aesKey);
|
||||
int size = [self getEncryptSize:data];
|
||||
unsigned char* buffer = malloc(size);
|
||||
unsigned char* blockRoundedBuffer = calloc(1, size);
|
||||
memcpy(blockRoundedBuffer, [data bytes], [data length]);
|
||||
|
||||
// AES_encrypt only encrypts the first 16 bytes so iterate the entire buffer
|
||||
int blockOffset = 0;
|
||||
while (blockOffset < size) {
|
||||
AES_encrypt(blockRoundedBuffer + blockOffset, buffer + blockOffset, &aesKey);
|
||||
blockOffset += 16;
|
||||
}
|
||||
|
||||
NSData* encryptedData = [NSData dataWithBytes:buffer length:size];
|
||||
free(buffer);
|
||||
free(blockRoundedBuffer);
|
||||
return encryptedData;
|
||||
}
|
||||
|
||||
- (NSData*) aesDecrypt:(NSData*)data withKey:(NSData*)key {
|
||||
AES_KEY aesKey;
|
||||
AES_set_decrypt_key([key bytes], 128, &aesKey);
|
||||
unsigned char* buffer = malloc([data length]);
|
||||
|
||||
// AES_decrypt only decrypts the first 16 bytes so iterate the entire buffer
|
||||
int blockOffset = 0;
|
||||
while (blockOffset < [data length]) {
|
||||
AES_decrypt([data bytes] + blockOffset, buffer + blockOffset, &aesKey);
|
||||
blockOffset += 16;
|
||||
}
|
||||
|
||||
NSData* decryptedData = [NSData dataWithBytes:buffer length:[data length]];
|
||||
free(buffer);
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
- (int) getEncryptSize:(NSData*)data {
|
||||
// the size is the length of the data ceiling to the nearest 16 bytes
|
||||
return (([data length] + 15) / 16) * 16;
|
||||
}
|
||||
|
||||
- (bool) verifySignature:(NSData *)data withSignature:(NSData*)signature andCert:(NSData*)cert {
|
||||
const char* buffer = [cert bytes];
|
||||
X509* x509;
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
BIO_puts(bio, buffer);
|
||||
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||
|
||||
BIO_free(bio);
|
||||
|
||||
if (!x509) {
|
||||
fprintf(stderr, "unable to parse certificate in memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EVP_PKEY* pubKey = X509_get_pubkey(x509);
|
||||
EVP_MD_CTX *mdctx = NULL;
|
||||
mdctx = EVP_MD_CTX_create();
|
||||
EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pubKey);
|
||||
EVP_DigestVerifyUpdate(mdctx, [data bytes], [data length]);
|
||||
int result = EVP_DigestVerifyFinal(mdctx, (unsigned char*)[signature bytes], [signature length]);
|
||||
|
||||
X509_free(x509);
|
||||
EVP_PKEY_free(pubKey);
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
- (NSData *)signData:(NSData *)data withKey:(NSData *)key {
|
||||
const char* buffer = [key bytes];
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
BIO_puts(bio, buffer);
|
||||
|
||||
EVP_PKEY* pkey;
|
||||
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
||||
|
||||
BIO_free(bio);
|
||||
|
||||
if (!pkey) {
|
||||
fprintf(stderr, "unable to parse private key in memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
EVP_MD_CTX *mdctx = NULL;
|
||||
mdctx = EVP_MD_CTX_create();
|
||||
ret = EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey);
|
||||
ret = EVP_DigestSignUpdate(mdctx, [data bytes], [data length]);
|
||||
size_t slen;
|
||||
ret = EVP_DigestSignFinal(mdctx, NULL, &slen);
|
||||
unsigned char* signature = malloc(slen);
|
||||
int result = EVP_DigestSignFinal(mdctx, signature, &slen);
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
|
||||
if (result <= 0) {
|
||||
free(signature);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NSData* signedData = [NSData dataWithBytes:signature length:slen];
|
||||
free(signature);
|
||||
|
||||
return signedData;
|
||||
}
|
||||
|
||||
// TODO: these three methods are almost identical, fix the copy-pasta
|
||||
+ (NSData*) readCertFromFile {
|
||||
@@ -34,6 +162,20 @@
|
||||
return [NSData dataWithContentsOfFile:keyFile];
|
||||
}
|
||||
|
||||
+ (NSData *)getSignatureFromCert:(NSData *)cert {
|
||||
const char* buffer = [cert bytes];
|
||||
X509* x509;
|
||||
BIO* bio = BIO_new(BIO_s_mem());
|
||||
BIO_puts(bio, buffer);
|
||||
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||
|
||||
if (!x509) {
|
||||
fprintf(stderr, "unable to parse certificate in memory\n");
|
||||
return NULL;
|
||||
}
|
||||
return [NSData dataWithBytes:x509->signature->data length:x509->signature->length];
|
||||
}
|
||||
|
||||
+ (void) generateKeyPairUsingSSl {
|
||||
NSLog(@"Generating Certificate... ");
|
||||
CertKeyPair certKeyPair = generateCertKeyPair();
|
||||
|
||||
@@ -9,8 +9,19 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
||||
|
||||
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag;
|
||||
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert;
|
||||
- (NSString*) generatePIN;
|
||||
- (NSData*) saltPIN:(NSString*)PIN;
|
||||
- (NSURL*) newPairRequest;
|
||||
- (NSURLRequest*) newPairRequest:(NSData*)salt;
|
||||
- (NSURLRequest*) newUnpairRequest;
|
||||
- (NSURLRequest*) newChallengeRequest:(NSData*)challenge;
|
||||
- (NSURLRequest*) newChallengeRespRequest:(NSData*)challengeResp;
|
||||
- (NSURLRequest*) newClientSecretRespRequest:(NSString*)clientPairSecret;
|
||||
- (NSURLRequest*) newPairChallenge;
|
||||
- (NSURLRequest*) newAppListRequest;
|
||||
- (NSURLRequest*) newServerInfoRequest;
|
||||
- (NSData*) executeRequestSynchronously:(NSURLRequest*)request;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@@ -9,17 +9,70 @@
|
||||
#import "HttpManager.h"
|
||||
#import "CryptoManager.h"
|
||||
|
||||
#include <libxml2/libxml/xmlreader.h>
|
||||
#include <string.h>
|
||||
|
||||
@implementation HttpManager {
|
||||
NSString* _baseURL;
|
||||
NSString* _host;
|
||||
NSString* _uniqueId;
|
||||
NSString* _deviceName;
|
||||
NSData* _salt;
|
||||
NSData* _cert;
|
||||
NSMutableData* _respData;
|
||||
NSData* _requestResp;
|
||||
dispatch_semaphore_t _requestLock;
|
||||
}
|
||||
|
||||
static const NSString* PORT = @"47984";
|
||||
|
||||
+ (NSString*) getStringFromXML:(NSData*)xml tag:(NSString*)tag {
|
||||
xmlDocPtr docPtr = xmlParseMemory([xml bytes], [xml length]);
|
||||
|
||||
if (docPtr == NULL) {
|
||||
NSLog(@"ERROR: An error occured trying to parse xml.");
|
||||
return NULL;
|
||||
}
|
||||
NSString* value;
|
||||
xmlNodePtr node;
|
||||
xmlNodePtr rootNode = node = xmlDocGetRootElement(docPtr);
|
||||
|
||||
// Check root status_code
|
||||
if (![HttpManager verifyStatus: rootNode]) {
|
||||
//TODO: handle error
|
||||
}
|
||||
|
||||
// Skip the root node
|
||||
node = node->children;
|
||||
|
||||
while (node != NULL) {
|
||||
//NSLog(@"node: %s", node->name);
|
||||
if (!xmlStrcmp(node->name, (const xmlChar*)[tag UTF8String])) {
|
||||
xmlChar* nodeVal = xmlNodeListGetString(docPtr, node->xmlChildrenNode, 1);
|
||||
value = [[NSString alloc] initWithCString:(const char*)nodeVal encoding:NSUTF8StringEncoding];
|
||||
xmlFree(nodeVal);
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
//NSLog(@"xmlValue: %@", value);
|
||||
xmlFree(rootNode);
|
||||
xmlFree(docPtr);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (bool) verifyStatus:(xmlNodePtr)docRoot {
|
||||
xmlChar* statusStr = xmlGetProp(docRoot, (const xmlChar*)"status_code");
|
||||
NSLog(@"status: %s", statusStr);
|
||||
int status = [[NSString stringWithUTF8String:(const char*)statusStr] intValue];
|
||||
xmlFree(statusStr);
|
||||
return status == 200;
|
||||
}
|
||||
|
||||
+ (NSData*) fixXmlVersion:(NSData*) xmlData {
|
||||
NSString* xmlString = [[[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:@"UTF-16" withString:@"UTF-8" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [xmlData length])];
|
||||
//NSLog(@"xmlString: %@", xmlString);
|
||||
return [NSData dataWithBytes:[xmlString UTF8String] length:[xmlString length]];
|
||||
}
|
||||
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert {
|
||||
self = [super init];
|
||||
@@ -29,15 +82,72 @@ static const NSString* PORT = @"47984";
|
||||
_cert = cert;
|
||||
_baseURL = [[NSString stringWithFormat:@"https://%@:%@", host, PORT]
|
||||
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
_requestLock = dispatch_semaphore_create(0);
|
||||
_respData = [[NSMutableData alloc] init];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSURL*) newPairRequest {
|
||||
//NSLog(@"host: %@ \nport: %@ \nuniqueID: %@ \ndeviceName: %@ \nsalt: %@ \ncert: %@", _host, PORT, _uniqueId, _deviceName, salt, cert);
|
||||
NSString* urlString = [[NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=getservercert&salt=%@&clientcert=%@", _baseURL, _uniqueId, _deviceName, [self bytesToHex:_salt], [self bytesToHex:_cert]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSURL* url = [[NSURL alloc] initWithString:urlString];
|
||||
//NSLog(@"pair url: %@", url);
|
||||
return url;
|
||||
- (NSData*) executeRequestSynchronously:(NSURLRequest*)request {
|
||||
NSLog(@"Making Request: %@", request);
|
||||
[_respData setLength:0];
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[NSURLConnection connectionWithRequest:request delegate:self];
|
||||
});
|
||||
dispatch_semaphore_wait(_requestLock, DISPATCH_TIME_FOREVER);
|
||||
return _requestResp;
|
||||
}
|
||||
|
||||
- (void) executeRequest:(NSURLRequest*)request {
|
||||
[NSURLConnection connectionWithRequest:request delegate:self];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) createRequestFromString:(NSString*) urlString {
|
||||
NSString* escapedUrl = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSURL* url = [[NSURL alloc] initWithString:escapedUrl];
|
||||
return [NSURLRequest requestWithURL:url];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newPairRequest:(NSData*)salt {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=getservercert&salt=%@&clientcert=%@",
|
||||
_baseURL, _uniqueId, _deviceName, [self bytesToHex:salt], [self bytesToHex:_cert]];
|
||||
return [self createRequestFromString:urlString];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newUnpairRequest {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/unpair?uniqueid=%@", _baseURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newChallengeRequest:(NSData*)challenge {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientchallenge=%@",
|
||||
_baseURL, _uniqueId, _deviceName, [self bytesToHex:challenge]];
|
||||
return [self createRequestFromString:urlString];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newChallengeRespRequest:(NSData*)challengeResp {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&serverchallengeresp=%@",
|
||||
_baseURL, _uniqueId, _deviceName, [self bytesToHex:challengeResp]];
|
||||
return [self createRequestFromString:urlString];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newClientSecretRespRequest:(NSString*)clientPairSecret {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientpairingsecret=%@", _baseURL, _uniqueId, _deviceName, clientPairSecret];
|
||||
return [self createRequestFromString:urlString];
|
||||
}
|
||||
|
||||
- (NSURLRequest*) newPairChallenge {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=pairchallenge", _baseURL, _uniqueId, _deviceName];
|
||||
return [self createRequestFromString:urlString];
|
||||
}
|
||||
|
||||
- (NSURLRequest *)newAppListRequest {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/applist?uniqueid=%@", _baseURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString];
|
||||
}
|
||||
|
||||
- (NSURLRequest *)newServerInfoRequest {
|
||||
NSString* urlString = [NSString stringWithFormat:@"%@/serverinfo?uniqueid=%@", _baseURL, _uniqueId];
|
||||
return [self createRequestFromString:urlString];
|
||||
}
|
||||
|
||||
- (NSString*) bytesToHex:(NSData*)data {
|
||||
@@ -49,50 +159,27 @@ static const NSString* PORT = @"47984";
|
||||
return hex;
|
||||
}
|
||||
|
||||
- (NSString*) generatePIN {
|
||||
NSString* PIN = [NSString stringWithFormat:@"%d%d%d%d",
|
||||
arc4random() % 10, arc4random() % 10,
|
||||
arc4random() % 10, arc4random() % 10];
|
||||
NSLog(@"PIN: %@", PIN);
|
||||
return PIN;
|
||||
}
|
||||
|
||||
- (NSData*) saltPIN:(NSString*)PIN {
|
||||
NSMutableData* saltedPIN = [[NSMutableData alloc] initWithCapacity:20];
|
||||
[saltedPIN appendData:[self randomBytes:16]];
|
||||
[saltedPIN appendBytes:[PIN UTF8String] length:4];
|
||||
|
||||
//NSLog(@"Salted PIN: %@", [saltedPIN description]);
|
||||
_salt = saltedPIN;
|
||||
return saltedPIN;
|
||||
}
|
||||
|
||||
- (NSData*) randomBytes:(NSInteger)length {
|
||||
char* bytes = malloc(length);
|
||||
arc4random_buf(bytes, length);
|
||||
NSData* randomData = [NSData dataWithBytes:bytes length:length];
|
||||
free(bytes);
|
||||
return randomData;
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
||||
NSLog(@"Received response: %@", response);
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
NSLog(@"Received data: %@", data);
|
||||
NSLog(@"Received data: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
|
||||
[_respData appendData:data];
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
_requestResp = [HttpManager fixXmlVersion:_respData];
|
||||
dispatch_semaphore_signal(_requestLock);
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
|
||||
SecIdentityRef identity = [self getClientCertificate]; // Go get a SecIdentityRef
|
||||
CFArrayRef certs = [self getCertificate:identity]; // Get an array of certificates
|
||||
// Convert the CFArrayRef to a NSArray
|
||||
NSArray *myArray = (__bridge NSArray *)certs;
|
||||
NSArray *certArray = (__bridge NSArray *)certs;
|
||||
|
||||
// Create the NSURLCredential
|
||||
NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:myArray persistence:NSURLCredentialPersistencePermanent];
|
||||
NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:certArray persistence:NSURLCredentialPersistencePermanent];
|
||||
|
||||
// Send
|
||||
[challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge];
|
||||
}
|
||||
|
||||
@@ -103,35 +190,32 @@ static const NSString* PORT = @"47984";
|
||||
SecIdentityCopyCertificate(identity, &certificate);
|
||||
SecCertificateRef certs[1] = { certificate };
|
||||
|
||||
CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL);
|
||||
CFArrayRef certArray = CFArrayCreate(NULL, (const void **) certs, 1, NULL);
|
||||
|
||||
SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
|
||||
SecTrustRef myTrust;
|
||||
SecPolicyRef policyRef = SecPolicyCreateBasicX509();
|
||||
SecTrustRef trustRef;
|
||||
|
||||
OSStatus status = SecTrustCreateWithCertificates(array, myPolicy, &myTrust);
|
||||
if (status == noErr) {
|
||||
NSLog(@"No Err creating certificate");
|
||||
} else {
|
||||
NSLog(@"Possible Err Creating certificate");
|
||||
OSStatus status = SecTrustCreateWithCertificates(certArray, policyRef, &trustRef);
|
||||
if (status != noErr) {
|
||||
NSLog(@"Error Creating certificate");
|
||||
}
|
||||
return array;
|
||||
return certArray;
|
||||
}
|
||||
|
||||
// Returns the identity
|
||||
- (SecIdentityRef)getClientCertificate {
|
||||
SecIdentityRef identityApp = nil;
|
||||
NSData *PKCS12Data = [CryptoManager readP12FromFile];
|
||||
CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
|
||||
|
||||
CFStringRef password = CFSTR("limelight"); // no password
|
||||
const void *keys[] = { kSecImportExportPassphrase };//kSecImportExportPassphrase };
|
||||
CFDataRef p12Data = (__bridge CFDataRef)[CryptoManager readP12FromFile];
|
||||
|
||||
CFStringRef password = CFSTR("limelight");
|
||||
const void *keys[] = { kSecImportExportPassphrase };
|
||||
const void *values[] = { password };
|
||||
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
|
||||
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
|
||||
OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);
|
||||
OSStatus securityError = SecPKCS12Import(p12Data, options, &items);
|
||||
|
||||
if (securityError == errSecSuccess) {
|
||||
NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items));
|
||||
//NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items));
|
||||
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
|
||||
identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
|
||||
} else {
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
#import "Computer.h"
|
||||
#import "CryptoManager.h"
|
||||
#import "HttpManager.h"
|
||||
#import "PairManager.h"
|
||||
|
||||
@implementation MainFrameViewController
|
||||
NSString* hostAddr = @"cement-truck.case.edu";
|
||||
NSString* hostAddr;
|
||||
MDNSManager* mDNSManager;
|
||||
|
||||
+ (const char*)getHostAddr
|
||||
@@ -24,7 +25,15 @@ MDNSManager* mDNSManager;
|
||||
- (void)PairButton:(UIButton *)sender
|
||||
{
|
||||
NSLog(@"Pair Button Pressed!");
|
||||
[ConnectionHandler pairWithHost:hostAddr];
|
||||
[CryptoManager generateKeyPairUsingSSl];
|
||||
NSString* uniqueId = [CryptoManager getUniqueID];
|
||||
NSData* cert = [CryptoManager readCertFromFile];
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddr uniqueId:uniqueId deviceName:@"roth" cert:cert];
|
||||
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:cert];
|
||||
|
||||
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
|
||||
[opQueue addOperation:pMan];
|
||||
}
|
||||
|
||||
- (void)StreamButton:(UIButton *)sender
|
||||
@@ -50,9 +59,9 @@ MDNSManager* mDNSManager;
|
||||
|
||||
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
|
||||
{
|
||||
//self.hostPickerVals = [mDNSManager getFoundHosts];
|
||||
self.hostPickerVals = [mDNSManager getFoundHosts];
|
||||
|
||||
//[self.HostPicker reloadAllComponents];
|
||||
[self.HostPicker reloadAllComponents];
|
||||
if (pickerView == self.HostPicker) {
|
||||
hostAddr = ((Computer*)([self.hostPickerVals objectAtIndex:[self.HostPicker selectedRowInComponent:0]])).hostName;
|
||||
}
|
||||
@@ -85,21 +94,9 @@ MDNSManager* mDNSManager;
|
||||
self.streamConfigVals = [[NSArray alloc] initWithObjects:@"1280x720 (30Hz)", @"1280x720 (60Hz)", @"1920x1080 (30Hz)", @"1920x1080 (60Hz)",nil];
|
||||
self.hostPickerVals = [[NSArray alloc] init];
|
||||
|
||||
|
||||
mDNSManager = [[MDNSManager alloc] initWithCallback:self];
|
||||
//[mDNSManager searchForHosts];
|
||||
|
||||
[CryptoManager generateKeyPairUsingSSl];
|
||||
NSString* uniqueId = [CryptoManager getUniqueID];
|
||||
NSData* cert = [CryptoManager readCertFromFile];
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddr uniqueId:uniqueId deviceName:@"roth" cert:cert];
|
||||
NSString* PIN = [hMan generatePIN];
|
||||
NSData* saltedPIN = [hMan saltPIN:PIN];
|
||||
NSLog(@"PIN: %@, saltedPIN: %@", PIN, saltedPIN);
|
||||
NSURL* pairUrl = [hMan newPairRequest];
|
||||
NSURLRequest* pairRequest = [[NSURLRequest alloc] initWithURL:pairUrl];
|
||||
// NSLog(@"making pair request: %@", [pairRequest description]);
|
||||
[NSURLConnection connectionWithRequest:pairRequest delegate:hMan];
|
||||
[mDNSManager searchForHosts];
|
||||
}
|
||||
|
||||
- (void)updateHosts:(NSArray *)hosts {
|
||||
|
||||
17
Limelight/PairManager.h
Normal file
17
Limelight/PairManager.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// PairManager.h
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/19/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "HttpManager.h"
|
||||
|
||||
@interface PairManager : NSOperation
|
||||
- (id) initWithManager:(HttpManager*)httpManager andCert:(NSData*)cert;
|
||||
- (NSString*) generatePIN;
|
||||
- (NSData*) saltPIN:(NSString*)PIN;
|
||||
- (void) initiatePair;
|
||||
@end
|
||||
158
Limelight/PairManager.m
Normal file
158
Limelight/PairManager.m
Normal file
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// PairManager.m
|
||||
// Limelight
|
||||
//
|
||||
// Created by Diego Waxemberg on 10/19/14.
|
||||
// Copyright (c) 2014 Limelight Stream. All rights reserved.
|
||||
//
|
||||
|
||||
#import "PairManager.h"
|
||||
#import "CryptoManager.h"
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
@implementation PairManager {
|
||||
HttpManager* _httpManager;
|
||||
NSData* _cert;
|
||||
}
|
||||
|
||||
- (id) initWithManager:(HttpManager*)httpManager andCert:(NSData*)cert {
|
||||
self = [super init];
|
||||
_httpManager = httpManager;
|
||||
_cert = cert;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) main {
|
||||
[self initiatePair];
|
||||
}
|
||||
|
||||
- (void) initiatePair {
|
||||
NSString* PIN = [self generatePIN];
|
||||
NSData* salt = [self saltPIN:PIN];
|
||||
NSLog(@"PIN: %@, saltedPIN: %@", PIN, salt);
|
||||
|
||||
NSData* pairResp = [_httpManager executeRequestSynchronously:[_httpManager newPairRequest:salt]];
|
||||
if ([[HttpManager getStringFromXML:pairResp tag:@"paired"] intValue] != 1) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
return;
|
||||
}
|
||||
|
||||
NSString* plainCert = [HttpManager getStringFromXML:pairResp tag:@"plaincert"];
|
||||
|
||||
CryptoManager* cryptoMan = [[CryptoManager alloc] init];
|
||||
NSData* aesKey = [cryptoMan createAESKeyFromSalt:salt];
|
||||
|
||||
NSData* randomChallenge = [self randomBytes:16];
|
||||
NSData* encryptedChallenge = [cryptoMan aesEncrypt:randomChallenge withKey:aesKey];
|
||||
|
||||
NSData* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
|
||||
if ([[HttpManager getStringFromXML:challengeResp tag:@"paired"] intValue] != 1) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* encServerChallengeResp = [self hexToBytes:[HttpManager getStringFromXML:challengeResp tag:@"challengeresponse"]];
|
||||
NSData* decServerChallengeResp = [cryptoMan aesDecrypt:encServerChallengeResp withKey:aesKey];
|
||||
|
||||
NSData* serverResponse = [decServerChallengeResp subdataWithRange:NSMakeRange(0, 20)];
|
||||
NSData* serverChallenge = [decServerChallengeResp subdataWithRange:NSMakeRange(20, 16)];
|
||||
|
||||
NSData* clientSecret = [self randomBytes:16];
|
||||
NSData* challengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:serverChallenge with:[CryptoManager getSignatureFromCert:_cert]] with:clientSecret]];
|
||||
NSData* challengeRespEncrypted = [cryptoMan aesEncrypt:challengeRespHash withKey:aesKey];
|
||||
|
||||
NSData* secretResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRespRequest:challengeRespEncrypted]];
|
||||
if ([[HttpManager getStringFromXML:secretResp tag:@"paired"] intValue] != 1) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* serverSecretResp = [self hexToBytes:[HttpManager getStringFromXML:secretResp tag:@"pairingsecret"]];
|
||||
NSData* serverSecret = [serverSecretResp subdataWithRange:NSMakeRange(0, 16)];
|
||||
NSData* serverSignature = [serverSecretResp subdataWithRange:NSMakeRange(16, 256)];
|
||||
|
||||
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[self hexToBytes:plainCert]]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* serverChallengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:randomChallenge with:[CryptoManager getSignatureFromCert:[self hexToBytes:plainCert]]] with:serverSecret]];
|
||||
if (![serverChallengeRespHash isEqual:serverResponse]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* clientPairingSecret = [self concatData:clientSecret with:[cryptoMan signData:clientSecret withKey:[CryptoManager readKeyFromFile]]];
|
||||
NSData* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[self bytesToHex:clientPairingSecret]]];
|
||||
if (![[HttpManager getStringFromXML:clientSecretResp tag:@"paired"] isEqual:@"1"]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
return;
|
||||
}
|
||||
|
||||
NSData* clientPairChallenge = [_httpManager executeRequestSynchronously:[_httpManager newPairChallenge]];
|
||||
if (![[HttpManager getStringFromXML:clientPairChallenge tag:@"paired"] isEqual:@"1"]) {
|
||||
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSData*) concatData:(NSData*)data with:(NSData*)moreData {
|
||||
NSMutableData* concatData = [[NSMutableData alloc] initWithData:data];
|
||||
[concatData appendData:moreData];
|
||||
return concatData;
|
||||
}
|
||||
|
||||
- (NSString*) generatePIN {
|
||||
NSString* PIN = [NSString stringWithFormat:@"%d%d%d%d",
|
||||
arc4random() % 10, arc4random() % 10,
|
||||
arc4random() % 10, arc4random() % 10];
|
||||
NSLog(@"PIN: %@", PIN);
|
||||
return PIN;
|
||||
}
|
||||
|
||||
- (NSData*) saltPIN:(NSString*)PIN {
|
||||
NSMutableData* saltedPIN = [[NSMutableData alloc] initWithCapacity:20];
|
||||
[saltedPIN appendData:[self randomBytes:16]];
|
||||
[saltedPIN appendBytes:[PIN UTF8String] length:4];
|
||||
|
||||
//NSLog(@"Salted PIN: %@", [saltedPIN description]);
|
||||
return saltedPIN;
|
||||
}
|
||||
|
||||
- (NSData*) randomBytes:(NSInteger)length {
|
||||
char* bytes = malloc(length);
|
||||
arc4random_buf(bytes, length);
|
||||
NSData* randomData = [NSData dataWithBytes:bytes length:length];
|
||||
free(bytes);
|
||||
return randomData;
|
||||
}
|
||||
|
||||
- (NSData*) hexToBytes:(NSString*) hex {
|
||||
int len = [hex length];
|
||||
NSMutableData* data = [NSMutableData dataWithCapacity:len / 2];
|
||||
char byteChars[3] = {'\0','\0','\0'};
|
||||
unsigned long wholeByte;
|
||||
|
||||
const char *chars = [hex UTF8String];
|
||||
int i = 0;
|
||||
while (i < len) {
|
||||
byteChars[0] = chars[i++];
|
||||
byteChars[1] = chars[i++];
|
||||
wholeByte = strtoul(byteChars, NULL, 16);
|
||||
[data appendBytes:&wholeByte length:1];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
- (NSString*) bytesToHex:(NSData*)data {
|
||||
const unsigned char* bytes = [data bytes];
|
||||
NSMutableString *hex = [[NSMutableString alloc] init];
|
||||
for (int i = 0; i < [data length]; i++) {
|
||||
[hex appendFormat:@"%02X" , bytes[i]];
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user