pairing works!

This commit is contained in:
Diego Waxemberg
2014-10-20 02:59:16 -04:00
parent 13f39e30f6
commit b8d256b73d
8 changed files with 500 additions and 354 deletions

View File

@@ -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 */,

View File

@@ -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

View File

@@ -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();

View File

@@ -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

View File

@@ -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 {

View File

@@ -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
View 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
View 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