Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Alright, guys. No more Mr. Nice Sparklepants. Sparkle now requires ei…

…ther DSA-signed updates or SSL transport. If you want to put your users at risk, you're going to have to comment out some code and recompile.

I included some scripts to help you along, though. IANASG (I Am Not a Security Guy), though, so if you know your shit, feel free to do it on your own as before.
  • Loading branch information...
commit 1d3ab8d6bb4f124f75d28d6141f0492021616462 1 parent e086aa1
@andymatuschak andymatuschak authored
View
22 SUBasicUpdateDriver.m
@@ -158,6 +158,16 @@ - (void)download:(NSURLDownload *)d decideDestinationWithSuggestedFilename:(NSSt
- (void)downloadDidFinish:(NSURLDownload *)d
{
+ // New in Sparkle 1.5: we're now checking signatures on all non-https downloads.
+ if (![[[[d request] URL] scheme] isEqualToString:@"https"])
+ {
+ if (![SUDSAVerifier validatePath:downloadPath withEncodedDSASignature:[updateItem DSASignature] withPublicDSAKey:[host publicDSAKey]])
+ {
+ [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SUSignatureError userInfo:[NSDictionary dictionaryWithObject:@"The update is improperly signed." forKey:NSLocalizedDescriptionKey]]];
+ return;
+ }
+ }
+
[self extractUpdate];
}
@@ -177,17 +187,7 @@ - (BOOL)download:(NSURLDownload *)download shouldDecodeSourceDataOfMIMEType:(NSS
}
- (void)extractUpdate
-{
- // DSA verification, if activated by the developer
- if ([[host objectForInfoDictionaryKey:SUExpectsDSASignatureKey] boolValue])
- {
- if (![SUDSAVerifier validatePath:downloadPath withEncodedDSASignature:[updateItem DSASignature] withPublicDSAKey:[host publicDSAKey]])
- {
- [self abortUpdateWithError:[NSError errorWithDomain:SUSparkleErrorDomain code:SUSignatureError userInfo:[NSDictionary dictionaryWithObject:@"The update is improperly signed." forKey:NSLocalizedDescriptionKey]]];
- return;
- }
- }
-
+{
SUUnarchiver *unarchiver = [SUUnarchiver unarchiverForPath:downloadPath];
if (!unarchiver)
{
View
4 Sparkle.xcodeproj/project.pbxproj
@@ -40,6 +40,7 @@
615AE3D00D64DC40001CA7BD /* SUModelTranslation.plist in Resources */ = {isa = PBXBuildFile; fileRef = 615AE3CF0D64DC40001CA7BD /* SUModelTranslation.plist */; };
6160E7E10D3B4A8800E9CD71 /* NTSynchronousTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 610EC1C00CF3914D00AE239E /* NTSynchronousTask.h */; settings = {ATTRIBUTES = (); }; };
61699BCC0DDB92BD005878A4 /* SUVersionComparisonTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 61227A140DB548B800AB99EA /* SUVersionComparisonTest.h */; settings = {ATTRIBUTES = (); }; };
+ 618E9CFD0E7328F1004646D8 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = 618E9CFC0E7328F1004646D8 /* dsa_pub.pem */; };
618FA5010DAE88B40026945C /* SUInstaller.h in Headers */ = {isa = PBXBuildFile; fileRef = 618FA4FF0DAE88B40026945C /* SUInstaller.h */; settings = {ATTRIBUTES = (); }; };
618FA5020DAE88B40026945C /* SUInstaller.m in Sources */ = {isa = PBXBuildFile; fileRef = 618FA5000DAE88B40026945C /* SUInstaller.m */; };
618FA5050DAE8AB80026945C /* SUPlainInstaller.h in Headers */ = {isa = PBXBuildFile; fileRef = 618FA5030DAE8AB80026945C /* SUPlainInstaller.h */; settings = {ATTRIBUTES = (); }; };
@@ -184,6 +185,7 @@
618915710E35937600B5E981 /* sv */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = sv; path = sv.lproj/SUUpdateAlert.nib; sourceTree = "<group>"; };
618915720E35937600B5E981 /* sv */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = sv; path = sv.lproj/SUAutomaticUpdateAlert.nib; sourceTree = "<group>"; };
618915730E35937600B5E981 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Sparkle.strings; sourceTree = "<group>"; };
+ 618E9CFC0E7328F1004646D8 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dsa_pub.pem; path = "Test Application/dsa_pub.pem"; sourceTree = "<group>"; };
618FA4FF0DAE88B40026945C /* SUInstaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SUInstaller.h; sourceTree = "<group>"; };
618FA5000DAE88B40026945C /* SUInstaller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SUInstaller.m; sourceTree = "<group>"; };
618FA5030DAE8AB80026945C /* SUPlainInstaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SUPlainInstaller.h; sourceTree = "<group>"; };
@@ -479,6 +481,7 @@
61B5F92C09C4CFD800B25A18 /* MainMenu.nib */,
61B5F92409C4CFC900B25A18 /* main.m */,
61B5F90409C4CEE200B25A18 /* Test Application-Info.plist */,
+ 618E9CFC0E7328F1004646D8 /* dsa_pub.pem */,
);
name = "Test Application Sources";
sourceTree = "<group>";
@@ -738,6 +741,7 @@
61B5F92F09C4CFD800B25A18 /* MainMenu.nib in Resources */,
61BBDF820A49220C00378739 /* Sparkle.icns in Resources */,
61072EB30DF2640C008FE88B /* ConfigFrameworkReleaseGCSupport.xcconfig in Resources */,
+ 618E9CFD0E7328F1004646D8 /* dsa_pub.pem in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
2  Test Application/Test Application-Info.plist
@@ -28,5 +28,7 @@
<string>http://www.andymatuschak.org/files/sparkletestcast.xml</string>
<key>SUEnableSystemProfiling</key>
<true/>
+ <key>SUPublicDSAKeyFile</key>
+ <string>dsa_pub.pem</string>
</dict>
</plist>
View
20 Test Application/dsa_priv.pem
@@ -0,0 +1,20 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIDPgIBAAKCAQEA9lmy8fAXdW9b6fBXQ6Us5B2dLZV+cR685tFlhPSKJDpicP1F
+pNRkGESZwPFJbnxUyVeHWVS9yLeMcKqllhcjd+i1oEFKX7LPXk5+zO745OwVWHIe
+0DLOIxhJ0mJHm7mH1YVGZYOVVYkPt+0Y/hDbQVK5DycSGAhgDiCZ+Obl+aDSD2xJ
+RZGnVOpu83dYJ/CoUYCHqWtpN4gW5Bbgm8Uz0/2qiyPjFvJEeI1yE04AZA3sOg1y
+1S/UrCbqeC3gBIs0xsskwWOW3zCWjvDWgfPrj65At0mVfq/yyGgXJlN71X5sONxR
+swZSbRn5T2i/BJPZUStWks5Nxq+7T3WmnaPbTwIVAJp+BByoy95V3x8wZg0q66eR
+ufiJAoIBABbxkX6C9Lt8zeDvvIpk8X4kmHBVIwVJcuICJTVzOAIBZsvFhPnYmUYe
+v93oPgjtAdYqPrYZlNrExQG1e7B1bhmgaT8hbXL6whxhqRHKlsJsboVHNQs3qAbx
+sOLvJnwgb3FD4xX4ZZSSRXSIGk62FxcaoLG+mSlirGM/SY4yZDpURSJUX6MHdUZa
+qHWWGL3b31pz3d9h6SPYv6H4T3ZReVtn+dXYh/41SWkQqEyhAsHGBvqpDwuYJCCI
+Mwuvwz0U/KcwiydDaFo900MC9S33zEpk/YUxgA9YsiY5+UvWSy5M/yvkKBkvkb+I
+G6DAMWtApWu0fDcLV6jA9JKXmcAwAIECggEBAPC0OJEnLkOwU1Ehop7o2XJbWDKN
+giFt44IO3l9gx1fu05HrieDbwAJTkRK7qNEA0yk1iMT2hMHHbwLRNddEsOJuUd7o
+iyKwqwkmCQ2Q1zYPBR09wag9NEr8xLSTQJCw9CpxTRSH+9hc1DeuwkwAnTEn7JiW
+WbcxVCRtmtaUlN7+dTozxqGJHpYF6WsqHMeuG7Ixnyf6he8Fz8mjxnrc7/l73gFL
+Q+IZvUSjzh2zqtqaejtcmlNcT+fGmEFKxpcLB3JP3uu8PN8MbS/R6j191f1ovuM9
+U4MO3RuT4xJF0OlwyWAnOEik1S1p+tNQciQ/Ipv8Ff3DDBct9YZPPlNGi+ICFHHD
+tP5yX7hMTJIykGaMuM44KJMM
+-----END DSA PRIVATE KEY-----
View
20 Test Application/dsa_pub.pem
@@ -0,0 +1,20 @@
+-----BEGIN PUBLIC KEY-----
+MIIDOzCCAi0GByqGSM44BAEwggIgAoIBAQD2WbLx8Bd1b1vp8FdDpSzkHZ0tlX5x
+Hrzm0WWE9IokOmJw/UWk1GQYRJnA8UlufFTJV4dZVL3It4xwqqWWFyN36LWgQUpf
+ss9eTn7M7vjk7BVYch7QMs4jGEnSYkebuYfVhUZlg5VViQ+37Rj+ENtBUrkPJxIY
+CGAOIJn45uX5oNIPbElFkadU6m7zd1gn8KhRgIepa2k3iBbkFuCbxTPT/aqLI+MW
+8kR4jXITTgBkDew6DXLVL9SsJup4LeAEizTGyyTBY5bfMJaO8NaB8+uPrkC3SZV+
+r/LIaBcmU3vVfmw43FGzBlJtGflPaL8Ek9lRK1aSzk3Gr7tPdaado9tPAhUAmn4E
+HKjL3lXfHzBmDSrrp5G5+IkCggEAFvGRfoL0u3zN4O+8imTxfiSYcFUjBUly4gIl
+NXM4AgFmy8WE+diZRh6/3eg+CO0B1io+thmU2sTFAbV7sHVuGaBpPyFtcvrCHGGp
+EcqWwmxuhUc1CzeoBvGw4u8mfCBvcUPjFfhllJJFdIgaTrYXFxqgsb6ZKWKsYz9J
+jjJkOlRFIlRfowd1RlqodZYYvdvfWnPd32HpI9i/ofhPdlF5W2f51diH/jVJaRCo
+TKECwcYG+qkPC5gkIIgzC6/DPRT8pzCLJ0NoWj3TQwL1LffMSmT9hTGAD1iyJjn5
+S9ZLLkz/K+QoGS+Rv4gboMAxa0Cla7R8NwtXqMD0kpeZwDAAgQOCAQYAAoIBAQDw
+tDiRJy5DsFNRIaKe6NlyW1gyjYIhbeOCDt5fYMdX7tOR64ng28ACU5ESu6jRANMp
+NYjE9oTBx28C0TXXRLDiblHe6IsisKsJJgkNkNc2DwUdPcGoPTRK/MS0k0CQsPQq
+cU0Uh/vYXNQ3rsJMAJ0xJ+yYllm3MVQkbZrWlJTe/nU6M8ahiR6WBelrKhzHrhuy
+MZ8n+oXvBc/Jo8Z63O/5e94BS0PiGb1Eo84ds6ramno7XJpTXE/nxphBSsaXCwdy
+T97rvDzfDG0v0eo9fdX9aL7jPVODDt0bk+MSRdDpcMlgJzhIpNUtafrTUHIkPyKb
+/BX9wwwXLfWGTz5TRovi
+-----END PUBLIC KEY-----
View
13 generate_key.rb
@@ -0,0 +1,13 @@
+#!/usr/bin/ruby
+["dsaparam.pem", "dsa_priv.pem", "dsa_pub.pem"].each do |file|
+ if File.exist? file
+ puts "There's already a #{file} here! Move it aside or be more careful!"
+ end
+end
+`openssl dsaparam 2048 < /dev/urandom > dsaparam.pem`
+`openssl gendsa dsaparam.pem -out dsa_priv.pem`
+`openssl dsa -in dsa_priv.pem -pubout -out dsa_pub.pem`
+`rm dsaparam.pem`
+puts "\nGenerated private and public keys: dsa_priv.pem and dsa_pub.pem.\n
+BACK UP YOUR PRIVATE KEY AND KEEP IT SAFE!\n
+If you lose it, your users will be unable to upgrade!\n"
View
7 sign_update.rb
@@ -0,0 +1,7 @@
+#!/usr/bin/ruby
+if ARGV.length < 2
+ puts "Usage: ruby sign_update.rb update_archive private_key"
+ exit
+end
+
+puts `openssl dgst -sha1 -binary < "#{ARGV[0]}" | openssl dgst -dss1 -sign "#{ARGV[1]}" | openssl enc -base64`
Please sign in to comment.
Something went wrong with that request. Please try again.