Skip to content

Commit

Permalink
Merge pull request #10 from cicada-solvers/fix-issue-8
Browse files Browse the repository at this point in the history
Fix issue #8 by detecting message type and calling proper methods + split header validation parsing
  • Loading branch information
crashdemons authored Mar 28, 2022
2 parents 24dc2b3 + 0b7b549 commit e1bc913
Show file tree
Hide file tree
Showing 56 changed files with 332 additions and 1,782 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
/nbproject/private/
*.ttf
*.otf
7 changes: 4 additions & 3 deletions about.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
<head>
<title>Is It Cicada?</title>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="reset.css">
<link rel="stylesheet" type="text/css" href="theme.css">
<script src="jquery-3.2.1.min.js"></script>
<link rel="icon" href="assets/images/favicon.ico">
<link rel="stylesheet" type="text/css" href="assets/css/reset.css">
<link rel="stylesheet" type="text/css" href="assets/css/app-theme.css">
<script src="assets/js/lib/jquery-3.2.1.min.js"></script>



Expand Down
6 changes: 3 additions & 3 deletions theme.css → assets/css/app-theme.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@font-face {
font-family: 'FuturaPT';
src: url('futura_pt.ttf') format('truetype'),
url('futura_ptb.otf') format('opentype');
src: url('../fonts/futura_pt.ttf') format('truetype'),
url('../fonts/futura_ptb.otf') format('opentype');

}

Expand All @@ -25,7 +25,7 @@ body{
textarea{
resize: none;
background-color:#000000;
background-image: url('logo.png');
background-image: url('../images/logo.png');
background-repeat: no-repeat;
background-attachment: fixed;
background-position: center;
Expand Down
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions assets/fonts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.ttf
*.otf
*.woff
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes.
2 changes: 1 addition & 1 deletion script.js → assets/js/app/app-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function input_failed(err, text) {

function load_key() {
$.ajax({
url: "cicada_3301_key.txt",
url: "assets/pgp/cicada_3301_key.txt",
data: '',
dataType: 'text',
success: function (response) {
Expand Down
38 changes: 38 additions & 0 deletions assets/js/app/initiallinematcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2022 crashdemons (crashenator at gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/


function InitialLineMatcher(section_markers){
this.reset();
this.match = null;
this.section_markers = section_markers;
}

//this is ugly and I hate prototypal inheritance + backporting
InitialLineMatcher.prototype = new Lineparser([],"outside-before");

InitialLineMatcher.prototype.change_section_by_marker = function(line){
for(var i=0;i<this.section_markers.length;i++){
if(line===this.section_markers[i]){
this.change_section(0,'message-started',this.section_markers[i]);
this.match = i;
this.stop();
return true;
}
}
return false;
};
File renamed without changes.
8 changes: 4 additions & 4 deletions pgpparser.js → assets/js/app/pgpclearsignparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ if (typeof Lineparser === "undefined") {
//a stateful text-line parser for pgp cleartext messages.
//the line callback is called when each line in a section of the message is processed
//the section-complete callback is called when all data for a section has been collected (the section was ended or moved onto the next section)
function PgpParser(line_callback,section_complete_callback){
function PgpClearsignParser(line_callback,section_complete_callback){
this.reset();
this.line_callback=line_callback;
this.section_complete_callback=section_complete_callback;
Expand All @@ -33,7 +33,7 @@ function PgpParser(line_callback,section_complete_callback){
}

//this is ugly and I hate prototypal inheritance + backporting
PgpParser.prototype = new Lineparser([
PgpClearsignParser.prototype = new Lineparser([
["msg-headers","-----BEGIN PGP SIGNED MESSAGE-----"],//define the starting conditions for each section
["content",""],
["sig-headers","-----BEGIN PGP SIGNATURE-----"],
Expand All @@ -42,13 +42,13 @@ PgpParser.prototype = new Lineparser([
],"outside-before");//define the initial section name

//record a fatal error from a callback function (stored in parserobject.final.error)
PgpParser.prototype.fail=function(error){
PgpClearsignParser.prototype.fail=function(error){
this.final.error=error;
this.stop();
};

//record a warning from a callback function (stored in parserobject.final.warnings)
PgpParser.prototype.warn=function(warning){
PgpClearsignParser.prototype.warn=function(warning){
if(this.final.warnings.indexOf(warning)===-1)
this.final.warnings.push(warning);
};
60 changes: 60 additions & 0 deletions assets/js/app/pgpparsing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (C) 2018 crashdemons (crashenator at gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/


if (typeof Lineparser === "undefined") {
var Lineparser = {};//suppress warnings in editor - doesn't change anything.
console.error("pgpparser code loaded before Lineparser");
}

if (typeof PgpClearsignParser === "undefined") {
var PgpClearsignParser = {};//suppress warnings in editor - doesn't change anything.
console.error("pgpparser code loaded before PgpClearsignParser");
}
if (typeof PgpSignParser === "undefined") {
var PgpSignParser = {};//suppress warnings in editor - doesn't change anything.
console.error("pgpparser code loaded before PgpSignParser");
}

if (typeof InitialLineMatcher === "undefined") {
var InitialLineMatcher = {};//suppress warnings in editor - doesn't change anything.
console.error("pgpparser code loaded before InitialLineMatcher");
}

var PgpParsing = {
parsers:{
CLEARSIGNED: 0,
SIGNED: 1
},
guessMessageType:function(cleartext){
var matcher = new InitialLineMatcher(["-----BEGIN PGP SIGNED MESSAGE-----","-----BEGIN PGP MESSAGE-----"]);
matcher.parse(cleartext);
if(matcher.match!==null) return matcher.match;
return PgpParsing.parsers.CLEARSIGNED;//choose this as default if we cannot determine the type, though this should mean that it is rejected anyway.
},

createParser:function(type,line_callback,section_complete_callback){
console.log("CreateParser",type);
switch(type){
case PgpParsing.parsers.SIGNED:
return new PgpSignParser(line_callback,section_complete_callback);
case PgpParsing.parsers.CLEARSIGNED:
return new PgpClearsignParser(line_callback,section_complete_callback);
}
return null;
}
};
52 changes: 52 additions & 0 deletions assets/js/app/pgpsignparser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2018 crashdemons (crashenator at gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/


if (typeof Lineparser === "undefined") {
var Lineparser = {};//suppress warnings in editor - doesn't change anything.
console.error("pgpparser code loaded before Lineparser");
}

//a stateful text-line parser for pgp cleartext messages.
//the line callback is called when each line in a section of the message is processed
//the section-complete callback is called when all data for a section has been collected (the section was ended or moved onto the next section)
function PgpSignParser(line_callback,section_complete_callback){
this.reset();
this.line_callback=line_callback;
this.section_complete_callback=section_complete_callback;
this.final.error=0;
this.final.warnings=[];
}

//this is ugly and I hate prototypal inheritance + backporting
PgpSignParser.prototype = new Lineparser([
["sig-headers","-----BEGIN PGP MESSAGE-----"],//define the starting conditions for each section
["signature",""],
["outside-after","-----END PGP MESSAGE-----"]
],"outside-before");//define the initial section name

//record a fatal error from a callback function (stored in parserobject.final.error)
PgpSignParser.prototype.fail=function(error){
this.final.error=error;
this.stop();
};

//record a warning from a callback function (stored in parserobject.final.warnings)
PgpSignParser.prototype.warn=function(warning){
if(this.final.warnings.indexOf(warning)===-1)
this.final.warnings.push(warning);
};
41 changes: 28 additions & 13 deletions pgputil.js → assets/js/app/pgputil.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ if (typeof openpgp === "undefined") {
var openpgp = {};//suppress warnings in editor - doesn't change anything.
console.error("PGPUtil loaded before OpenPGP");
}
if (typeof PgpParser === "undefined") {
var PgpParser = {};//suppress warnings in editor - doesn't change anything.
console.error("PGPUtil loaded before PgpParser");
if (typeof PgpParsing === "undefined") {
var PgpParsing = {};//suppress warnings in editor - doesn't change anything.
console.error("PGPUtil loaded before PgpParsing");
}

var pgputil = {
Expand Down Expand Up @@ -264,11 +264,12 @@ var pgputil = {
//combines format validation and signature verification into a single function.
verify_text: function (cleartext, pubobj, callback_verified, callback_failure) {
try {
var formatresult = this.verify_text_format(cleartext);
var formatType = PgpParsing.guessMessageType(cleartext);
var formatresult = this.verify_text_format(formatType,cleartext);
var formaterror = formatresult.error;
console.log("formaterror: " + formaterror);
if (formaterror === pgputil.error.NONE) {
return this.verify_text_signature(cleartext, pubobj).then(function (result) {
return this.verify_text_signature(formatType,cleartext, pubobj).then(function (result) {
result.warnings = formatresult.warnings;
callback_verified(result.validity,result.verified,result.error,formatresult.warnings);
return result;
Expand All @@ -284,7 +285,7 @@ var pgputil = {
return null;
},

//checks a clearsigned armor message against a pubkeyobj and calls a callback with the result
//checks a signed or clearsigned armor message against a pubkeyobj and calls a callback with the result
// validity = true (message was verified against the key)
// validity = false (message could not be verified against the key)
// error=0: Unknown reason
Expand All @@ -294,11 +295,25 @@ var pgputil = {
// error=4: bad signature for this message
//the calback will receive the validity, a verification result object, and the error code
// the verification object holds a list of signatures in verobj.signatures, of which you can check the validity with verobj.signatures[i].valid
verify_text_signature: function (cleartext, pubobj, callback_verified) {
verify_text_signature: function (formatType,cleartext, pubobj, callback_verified) {
var options = {
message: openpgp.cleartext.readArmored(cleartext), // parse armored message
//message: openpgp.message.readArmored(cleartext),
//message: openpgp.cleartext.readArmored(cleartext), // parse armored message
publicKeys: pubobj.keys // for verification
};//NOTE: only exceptions from Read will be caught from this function
};

//NOTE: only exceptions from Read will be caught from this function
switch(formatType){
case PgpParsing.parsers.SIGNED:
options.message=openpgp.message.readArmored(cleartext);
break;
case PgpParsing.parsers.CLEARSIGNED:
options.message=openpgp.cleartext.readArmored(cleartext);
break;
}



var result = openpgp.verify(options).then(function (verified) {
var validity = null;
var error = pgputil.error.NONE;
Expand All @@ -324,12 +339,12 @@ var pgputil = {
return result;
},

//checks a clearsigned armor message for discrepancies in formatting that are ignored by OpenPGP.js
//refer to this infographic for how this function validates messages https://i.imgur.com/AvultlA.png
verify_text_format: function (cleartext) {
//checks a signed or clearsigned armor message for discrepancies in formatting that are ignored by OpenPGP.js
//This infographic shows how messages are validated in the case of an example Clearsigned message https://i.imgur.com/AvultlA.png - a similar process with less states is followed for signed messages.
verify_text_format: function (formatType,cleartext) {
if (cleartext.length === 0)
return {error: pgputil.error.VERIFY_FORMAT_EMPTY, warnings: []};
var parser = new PgpParser(
var parser = new PgpParsing.createParser(formatType,
function line_complete(parser) {
if (parser.current.section === "msg-headers" || parser.current.section === "sig-headers") {
var header = {name: "", value: ""};
Expand Down
2 changes: 1 addition & 1 deletion tests/scripts.js → assets/js/app/test-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function testPgpInput_delayed(input_str){
}

$(function(){
tester.load_cases('pgp_cases.json',function(){
tester.load_cases('assets/json/test-cases.json',function(){
$('#status').text('Running test-cases...');
tester.test_cases(testPgpInput_delayed, addResult_callback,function(){
$('#status').text('Tests Ran.');
Expand Down
2 changes: 1 addition & 1 deletion tests/tester.js → assets/js/app/tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var tester = {
});
},
load_case_data: function (i, loaded_callback) {
var filename = "./cases/" + this.cases[i].id.toString() + ".txt";
var filename = "./assets/pgp/test-cases/" + this.cases[i].id.toString() + ".txt";
var tester_instance = this;
$.ajax({
dataType: "text",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions tests/pgp_cases.json → assets/json/test-cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
{"id":22,"name":"PGP Message - Empty File","expectation":"{validity:false,verified:null,error:1006,warnings:[]}"},
{"id":23,"name":"PGP Message - Valid message with before and after text","expectation":"{validity:true,verified:{},error:0,warnings:[2001,2003]}"},
{"id":24,"name":"PGP Message - A 'compressed' message made with --sign instead of --clearsign","expectation":"{validity:true,verified:{},error:0,warnings:[]}"},
{"id":27,"name":"PGP Message - Valid clearsigned message with embedded non-clearsigned message","expectation":"{validity:true,verified:{},error:0,warnings:[]}"},
{"id":25,"name":"PGP Message - Valid message with MessageID header","expectation":"{validity:true,verified:{},error:0,warnings:[2003]}"},
{"id":26,"name":"PGP Message - Valid message with Charset header","expectation":"{validity:true,verified:{},error:0,warnings:[2003]}"}
]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit e1bc913

Please sign in to comment.